Skip to content

Commit

Permalink
Refactor Minting Fee and Receiver Check Hooks into Unified LicensingH…
Browse files Browse the repository at this point in the history
…ook (#115)

* Add Unified Licensing Hook
* Refactor and add more tests
  • Loading branch information
kingster-will authored Apr 23, 2024
1 parent 96ebc7c commit f559e0b
Show file tree
Hide file tree
Showing 12 changed files with 617 additions and 214 deletions.
52 changes: 52 additions & 0 deletions contracts/interfaces/modules/licensing/ILicensingHook.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.23;

import { IModule } from "../base/IModule.sol";

/// @title ILicensingHook
/// @notice This interface defines the hook functions that are called by the LicensingModule when
/// executing licensing functions.
/// IP owners can configure the hook to a specific license terms or all licenses of an IP Asset.
/// @dev Developers can create a contract that implements this interface to implement various checks
/// and determine the minting price.
interface ILicensingHook is IModule {
/// @notice This function is called when the LicensingModule mints license tokens.
/// @dev The hook can be used to implement various checks and determine the minting price.
/// The hook should revert if the minting is not allowed.
/// @param caller The address of the caller who calling the mintLicenseTokens() function.
/// @param licensorIpId The ID of licensor IP from which issue the license tokens.
/// @param licenseTemplate The address of the license template.
/// @param licenseTermsId The ID of the license terms within the license template,
/// which is used to mint license tokens.
/// @param amount The amount of license tokens to mint.
/// @param receiver The address of the receiver who receive the license tokens.
/// @param hookData The data to be used by the licensing hook.
/// @return totalMintingFee The total minting fee to be paid when minting amount of license tokens.
function beforeMintLicenseTokens(
address caller,
address licensorIpId,
address licenseTemplate,
uint256 licenseTermsId,
uint256 amount,
address receiver,
bytes calldata hookData
) external returns (uint256 totalMintingFee);

/// @notice This function is called when the LicensingModule mints license tokens.
/// @dev The hook can be used to implement various checks and determine the minting price.
/// The hook should revert if the registering of derivative is not allowed.
/// @param childIpId The derivative IP ID.
/// @param parentIpId The parent IP ID.
/// @param licenseTemplate The address of the license template.
/// @param licenseTermsId The ID of the license terms within the license template.
/// @param hookData The data to be used by the licensing hook.
/// @return mintingFee The minting fee to be paid when register child IP to the parent IP as derivative.
function beforeRegisterDerivative(
address caller,
address childIpId,
address parentIpId,
address licenseTemplate,
uint256 licenseTermsId,
bytes calldata hookData
) external returns (uint256 mintingFee);
}
17 changes: 17 additions & 0 deletions contracts/interfaces/modules/licensing/ILicensingModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity 0.8.23;

import { IModule } from "../base/IModule.sol";
import { Licensing } from "../../../lib/Licensing.sol";

/// @title ILicensingModule
/// @notice This interface defines the entry point for users to manage licenses in the Story Protocol.
Expand Down Expand Up @@ -121,4 +122,20 @@ interface ILicensingModule is IModule {
uint256[] calldata licenseTokenIds,
bytes calldata royaltyContext
) external;

/// @notice Sets the licensing configuration for a specific license terms of an IP.
/// If both licenseTemplate and licenseTermsId are not specified then the licensing config apply
/// to all licenses of given IP.
/// @param ipId The address of the IP for which the configuration is being set.
/// @param licenseTemplate The address of the license template used.
/// If not specified, the configuration applies to all licenses.
/// @param licenseTermsId The ID of the license terms within the license template.
/// If not specified, the configuration applies to all licenses.
/// @param licensingConfig The licensing configuration for the license.
function setLicensingConfig(
address ipId,
address licenseTemplate,
uint256 licenseTermsId,
Licensing.LicensingConfig memory licensingConfig
) external;
}
29 changes: 0 additions & 29 deletions contracts/interfaces/modules/licensing/IMintingFeeModule.sol

This file was deleted.

23 changes: 10 additions & 13 deletions contracts/interfaces/registries/ILicenseRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ interface ILicenseRegistry {
event LicenseTemplateRegistered(address indexed licenseTemplate);

/// @notice Emitted when a minting license configuration is set.
event MintingLicenseConfigSetLicense(
event LicensingConfigSetForLicense(
address indexed ipId,
address indexed licenseTemplate,
uint256 indexed licenseTermsId
);

/// @notice Emitted when a minting license configuration is set for all licenses of an IP.
event MintingLicenseConfigSetForIP(address indexed ipId, Licensing.MintingLicenseConfig mintingLicenseConfig);
event LicensingConfigSetForIP(address indexed ipId, Licensing.LicensingConfig licensingConfig);

/// @notice Emitted when an expiration time is set for an IP.
event ExpirationTimeSet(address indexed ipId, uint256 expireTime);
Expand Down Expand Up @@ -75,7 +75,7 @@ interface ILicenseRegistry {
address licenseTemplate,
uint256 licenseTermsId,
bool isMintedByIpOwner
) external view returns (Licensing.MintingLicenseConfig memory);
) external view returns (Licensing.LicensingConfig memory);

/// @notice Attaches license terms to an IP.
/// @param ipId The address of the IP to which the license terms are attached.
Expand Down Expand Up @@ -149,34 +149,31 @@ interface ILicenseRegistry {
/// @param licenseTemplate The address of the license template where the license terms are defined.
/// @param licenseTermsId The ID of the license terms.
/// @return The configuration for minting the license.
function getMintingLicenseConfig(
function getLicensingConfig(
address ipId,
address licenseTemplate,
uint256 licenseTermsId
) external view returns (Licensing.MintingLicenseConfig memory);
) external view returns (Licensing.LicensingConfig memory);

/// @notice Sets the minting license configuration for a specific license attached to a specific IP.
/// @dev This function can only be called by the LicensingModule.
/// @param ipId The address of the IP for which the configuration is being set.
/// @param licenseTemplate The address of the license template used.
/// @param licenseTermsId The ID of the license terms within the license template.
/// @param mintingLicenseConfig The configuration for minting the license.
function setMintingLicenseConfigForLicense(
/// @param licensingConfig The configuration for minting the license.
function setLicensingConfigForLicense(
address ipId,
address licenseTemplate,
uint256 licenseTermsId,
Licensing.MintingLicenseConfig calldata mintingLicenseConfig
Licensing.LicensingConfig calldata licensingConfig
) external;

/// @notice Sets the MintingLicenseConfig for an IP and applies it to all licenses attached to the IP.
/// @dev This function will set a global configuration for all licenses under a specific IP.
/// However, this global configuration can be overridden by a configuration set at a specific license level.
/// @param ipId The IP ID for which the configuration is being set.
/// @param mintingLicenseConfig The MintingLicenseConfig to be set for all licenses under the given IP.
function setMintingLicenseConfigForIp(
address ipId,
Licensing.MintingLicenseConfig calldata mintingLicenseConfig
) external;
/// @param licensingConfig The MintingLicenseConfig to be set for all licenses under the given IP.
function setLicensingConfigForIp(address ipId, Licensing.LicensingConfig calldata licensingConfig) external;

/// @notice Sets the expiration time for an IP.
/// @param ipId The address of the IP.
Expand Down
9 changes: 9 additions & 0 deletions contracts/lib/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ library Errors {
/// @notice Zero address provided for License Token.
error LicensingModule__ZeroLicenseToken();

/// @notice Zero address provided for Module Registry.
error LicensingModule__ZeroModuleRegistry();

/// @notice Zero address provided for Licensing Module.
error LicenseRegistry__ZeroLicensingModule();

Expand Down Expand Up @@ -219,6 +222,12 @@ library Errors {
address licensorIpId
);

/// @notice Licensing hook is invalid either not support ILicensingHook interface or not registered as module
error LicensingModule__InvalidLicensingHook(address hook);

/// @notice The license terms ID is invalid or license template doesn't exist.
error LicensingModule__InvalidLicenseTermsId(address licenseTemplate, uint256 licenseTermsId);

////////////////////////////////////////////////////////////////////////////
// Dispute Module //
////////////////////////////////////////////////////////////////////////////
Expand Down
14 changes: 6 additions & 8 deletions contracts/lib/Licensing.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,18 @@ library Licensing {
/// @notice This struct is used by IP owners to define the configuration
/// when others are minting license tokens of their IP through the LicensingModule.
/// When the `mintLicenseTokens` function of LicensingModule is called, the LicensingModule will read
/// this configuration to determine the minting fee and who can receive the license tokens.
/// this configuration to determine the minting fee and execute the licensing hook if set.
/// IP owners can set these configurations for each License or set the configuration for the IP
/// so that the configuration applies to all licenses of the IP.
/// If both the license and IP have the configuration, then the license configuration takes precedence.
/// @param isSet Whether the configuration is set or not.
/// @param mintingFee The minting fee to be paid when minting license tokens.
/// @param mintingFeeModule The module that determines the minting fee.
/// @param receiverCheckModule The module that determines who can receive the license tokens.
/// @param receiverCheckData The data to be used by the receiver check module.
struct MintingLicenseConfig {
/// @param licensingHook The hook contract address for the licensing module, or address(0) if none
/// @param hookData The data to be used by the licensing hook.
struct LicensingConfig {
bool isSet;
uint256 mintingFee;
address mintingFeeModule;
address receiverCheckModule;
bytes receiverCheckData;
address licensingHook;
bytes hookData;
}
}
Loading

0 comments on commit f559e0b

Please sign in to comment.