Skip to content
This repository has been archived by the owner on Apr 30, 2024. It is now read-only.

Refactored Licensing from parameter based to framework based. #44

Merged
merged 21 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions contracts/interfaces/licensing/ILinkParamVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

pragma solidity ^0.8.23;

import { IParamVerifier } from "contracts/interfaces/licensing/IParamVerifier.sol";
import { IPolicyVerifier } from "contracts/interfaces/licensing/IPolicyVerifier.sol";

interface ILinkParamVerifier is IParamVerifier {
/// @title ILinkParamVerifier
/// @notice LicenseRegistry will call this to verify the linking an IP to its parent
/// with the policy referenced by the license in use.
interface ILinkParamVerifier is IPolicyVerifier {
function verifyLink(
uint256 licenseId,
address caller,
address ipId,
address parentIpId,
bytes calldata data
bytes calldata policyData
) external returns (bool);
}
15 changes: 8 additions & 7 deletions contracts/interfaces/licensing/IMintParamVerifier.sol
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.23;
import { IParamVerifier } from "contracts/interfaces/licensing/IParamVerifier.sol";
import { IPolicyVerifier } from "contracts/interfaces/licensing/IPolicyVerifier.sol";

interface IMintParamVerifier is IParamVerifier {
/// @title IMintParamVerifier
/// @notice LicenseRegistry will call this to verify the minting parameters are compliant
/// with the policy associated with the license to mint.
interface IMintParamVerifier is IPolicyVerifier {
function verifyMint(
address caller,
uint256 policyId,
bool policyAddedByLinking,
bool policyWasInherited,
address licensor,
address receiver,
uint256 mintAmount,
bytes memory data
bytes memory policyData
) external returns (bool);
}

}
15 changes: 0 additions & 15 deletions contracts/interfaces/licensing/IParamVerifier.sol

This file was deleted.

14 changes: 14 additions & 0 deletions contracts/interfaces/licensing/IPolicyFrameworkManager.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.23;

import { Licensing } from "contracts/lib/Licensing.sol";
import { IPolicyVerifier } from "contracts/interfaces/licensing/IPolicyVerifier.sol";

/// @title IPolicyFrameworkManager
/// @notice Interface to define a policy framework contract, that will
/// register itself into the LicenseRegistry to format policy into the LicenseRegistry
interface IPolicyFrameworkManager is IPolicyVerifier {
function licenseRegistry() external view returns (address);
function policyToJson(bytes memory policyData) external view returns (string memory);
}
11 changes: 11 additions & 0 deletions contracts/interfaces/licensing/IPolicyVerifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.23;

import { IERC165 } from "@openzeppelin/contracts/interfaces/IERC165.sol";

/// @title IPolicyVerifier
/// @notice Placeholder interface for verifying policy parameters.
interface IPolicyVerifier is IERC165 {

}
9 changes: 6 additions & 3 deletions contracts/interfaces/licensing/ITransferParamVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

pragma solidity ^0.8.23;

import { IParamVerifier } from "contracts/interfaces/licensing/IParamVerifier.sol";
import { IPolicyVerifier } from "contracts/interfaces/licensing/IPolicyVerifier.sol";

interface ITransferParamVerifier is IParamVerifier {
/// @title ITransferParamVerifier
/// @notice LicenseRegistry will call this to verify the transfer parameters are compliant
/// with the policy
interface ITransferParamVerifier is IPolicyVerifier {
function verifyTransfer(
uint256 licenseId,
address from,
address to,
uint256 amount,
bytes memory data
bytes memory policyData
) external returns (bool);
}
56 changes: 56 additions & 0 deletions contracts/interfaces/licensing/IUMLPolicyFrameworkManager.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.23;

import { Licensing } from "contracts/lib/Licensing.sol";
import { IPolicyFrameworkManager } from "contracts/interfaces/licensing/IPolicyFrameworkManager.sol";

/// @notice Licensing parameters for the UML standard
/// @param attribution Whether or not attribution is required when reproducing the work
/// @param transferable Whether or not the license is transferable
/// @param commercialUse Whether or not the work can be used commercially
/// @param commercialAttribution Whether or not attribution is required when reproducing the work commercially
/// @param commercializers List of commericializers that are allowed to commercially exploit the work. If empty
/// then no restrictions.
/// @param commercialRevShare Percentage of revenue that must be shared with the licensor
/// @param derivativesAllowed Whether or not the licensee can create derivatives of his work
/// @param derivativesAttribution Whether or not attribution is required for derivatives of the work
/// @param derivativesApproval Whether or not the licensor must approve derivatives of the work before they can be
/// linked to the licensor IP ID
/// @param derivativesReciprocal Whether or not the licensee must license derivatives of the work under the same terms.
/// @param derivativesRevShare Percentage of revenue that must be shared with the licensor for derivatives of the work
/// @param territories List of territories where the license is valid. If empty, global.
Ramarti marked this conversation as resolved.
Show resolved Hide resolved
/// @param distributionChannels List of distribution channels where the license is valid. Empty if no restrictions.
Ramarti marked this conversation as resolved.
Show resolved Hide resolved
struct UMLPolicy {
bool attribution;
bool transferable;
bool commercialUse;
bool commercialAttribution;
string[] commercializers;
uint256 commercialRevShare;
bool derivativesAllowed;
bool derivativesAttribution;
bool derivativesApproval;
bool derivativesReciprocal;
uint256 derivativesRevShare;
string[] territories;
Ramarti marked this conversation as resolved.
Show resolved Hide resolved
string[] distributionChannels;
}


/// @title IUMLPolicyFrameworkManager
/// @notice Defines the interface for a Policy Framework Manager compliant with the UML standard
interface IUMLPolicyFrameworkManager is IPolicyFrameworkManager {

/// @notice Emitted when a new policy is added to the registry
event UMLPolicyAdded(uint256 indexed policyId, UMLPolicy policy);

/// @notice Adds a new policy to the registry
/// @dev Must encode the policy into bytes to be stored in the LicenseRegistry
/// @param umlPolicy UMLPolicy compliant licensing term values
function addPolicy(UMLPolicy calldata umlPolicy) external returns (uint256 policyId);
/// @notice Fetchs a policy from the registry, decoding the raw bytes into a UMLPolicy struct
/// @param policyId The ID of the policy to fetch
/// @return policy The UMLPolicy struct
function getPolicy(uint256 policyId) external view returns (UMLPolicy memory policy);
}
113 changes: 82 additions & 31 deletions contracts/interfaces/registries/ILicenseRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,53 @@ pragma solidity ^0.8.23;

import { Licensing } from "contracts/lib/Licensing.sol";

/// @title ILicenseRegistry
/// @notice Interface for the LicenseRegistry contract, which is the main entry point for the licensing system.
Ramarti marked this conversation as resolved.
Show resolved Hide resolved
/// It is responsible for:
/// - Registering policy frameworks
/// - Registering policies
/// - Minting licenses
/// - Linking IP to its parent
/// - Verifying transfer parameters (through the ITransferParamVerifier interface implementation by the policy framework)
/// - Verifying linking parameters (through the ILinkParamVerifier interface implementation by the policy framework)
/// - Verifying policy parameters (through the IPolicyVerifier interface implementation by the policy framework)
interface ILicenseRegistry {
event LicenseFrameworkCreated(

/// @notice Emitted when a policy framework is created by registering a policy framework manager
/// @param creator The address that created the policy framework
/// @param frameworkId The id of the policy framework
/// @param framework The policy framework data
event PolicyFrameworkCreated(
address indexed creator,
uint256 indexed frameworkId,
Licensing.FrameworkCreationParams frameworkCreationParams
Licensing.PolicyFramework framework
);

/// @notice Emitted when a policy is added to the contract.
/// @param creator The address that created the policy
/// @param policyId The id of the policy
/// @param policy The policy data
event PolicyCreated(address indexed creator, uint256 indexed policyId, Licensing.Policy policy);

/// @notice Emitted when a policy is added to an IP
/// @param caller The address that called the function
/// @param ipId The id of the IP
/// @param policyId The id of the policy
/// @param index The index of the policy in the IP's policy list
/// @param inheritedPolicy Whether the policy was inherited from a parent IP (linking) or set by IP owner
event PolicyAddedToIpId(
address indexed caller,
address indexed ipId,
uint256 indexed policyId,
uint256 index,
bool setByLinking
bool inheritedPolicy
);

/// @notice Emitted when a license is minted
/// @param creator The address that created the license
/// @param receiver The address that received the license
/// @param licenseId The id of the license
/// @param amount The amount of licenses minted
/// @param licenseData The license data
event LicenseMinted(
address indexed creator,
address indexed receiver,
Expand All @@ -28,66 +58,87 @@ interface ILicenseRegistry {
Licensing.License licenseData
);

/// @notice Emitted when an IP is linked to its parent by burning a license
/// @param caller The address that called the function
/// @param ipId The id of the IP
/// @param parentIpId The id of the parent IP
event IpIdLinkedToParent(address indexed caller, address indexed ipId, address indexed parentIpId);

function addLicenseFramework(
Licensing.FrameworkCreationParams calldata fwCreation
) external returns (uint256 frameworkId);
/// @notice registers a policy framework into the contract
/// @param fw The policy framework data
/// @return frameworkId The id of the policy framework
function addPolicyFramework(Licensing.PolicyFramework calldata fw) external returns (uint256 frameworkId);

function addPolicyToIp(
address ipId,
Licensing.Policy memory pol
) external returns (uint256 policyId, bool isNew, uint256 indexOnIpId);
/// @notice registers a policy into the contract
/// @param pol The policy data
/// @return policyId The id of the policy
function addPolicy(Licensing.Policy memory pol) external returns (uint256 policyId);

/// @notice adds a policy to an IP policy list
/// @param ipId The id of the IP
/// @param polId The id of the policy
/// @return indexOnIpId The index of the policy in the IP's policy list
function addPolicyToIp(address ipId, uint256 polId) external returns (uint256 indexOnIpId);

function addPolicy(Licensing.Policy memory pol) external returns (uint256 policyId);

/// @notice mints a license to create derivative IP
/// @param policyId The id of the policy with the licensing parameters
/// @param licensorIpId The id of the licensor IP
/// @param amount The amount of licenses to mint
/// @param receiver The address that will receive the license
function mintLicense(
uint256 policyId,
address licensorIpId,
uint256 amount,
address receiver
) external returns (uint256 licenseId);

/// @notice links an IP to its parent IP, burning the license NFT and the policy allows it
/// @param licenseId The id of the license to burn
/// @param childIpId The id of the child IP
/// @param holder The address that holds the license
function linkIpToParent(uint256 licenseId, address childIpId, address holder) external;

///
/// Getters
///

/// @notice gets total number of policy frameworks in the contract
function totalFrameworks() external view returns (uint256);

function frameworkParam(uint256 frameworkId, string calldata name) external view returns (Licensing.Parameter memory);
/// @notice gets policy framework data by id
function framework(uint256 frameworkId) external view returns (Licensing.PolicyFramework memory);
/// @notice gets policy framework license template URL by id
function frameworkUrl(uint256 frameworkId) external view returns (string memory);

/// @notice gets total number of policies (framework parameter configurations) in the contract
function totalPolicies() external view returns (uint256);

/// @notice gets policy data by id
function policy(uint256 policyId) external view returns (Licensing.Policy memory pol);

/// @notice true if policy is defined in the contract
function isPolicyDefined(uint256 policyId) external view returns (bool);

/// @notice gets the policy ids for an IP
function policyIdsForIp(address ipId) external view returns (uint256[] memory policyIds);

/// @notice gets total number of policies for an IP
function totalPoliciesForIp(address ipId) external view returns (uint256);

/// @notice true if policy is part of an IP's policy list
function isPolicyIdSetForIp(address ipId, uint256 policyId) external view returns (bool);

/// @notice gets the policy ID for an IP by index on the IP's policy list
function policyIdForIpAtIndex(address ipId, uint256 index) external view returns (uint256 policyId);

/// @notice gets the policy for an IP by index on the IP's policy list
function policyForIpAtIndex(address ipId, uint256 index) external view returns (Licensing.Policy memory);

/// @notice gets the index of a policy in an IP's policy list
function indexOfPolicyForIp(address ipId, uint256 policyId) external view returns (uint256 index);

function isPolicySetByLinking(address ipId, uint256 policyId) external view returns (bool);

/// @notice true if the license was added to the IP by linking (burning a license)
function isPolicyInherited(address ipId, uint256 policyId) external view returns (bool);
/// @notice true if holder is the licensee for the license (owner of the license NFT), or derivative IP owner if
/// the license was added to the IP by linking (burning a license)
function isLicensee(uint256 licenseId, address holder) external view returns (bool);

/// @notice IP ID of the licensor for the license (parent IP)
function licensorIpId(uint256 licenseId) external view returns (address);
/// @notice license data (licensor, policy...) for the license id
function license(uint256 licenseId) external view returns (Licensing.License memory);
/// @notice true if an IP is a derivative of another IP
function isParent(address parentIpId, address childIpId) external view returns (bool);

/// @notice returns the parent IP IDs for an IP ID
function parentIpIds(address ipId) external view returns (address[] memory);

/// @notice total number of parents for an IP ID
function totalParentsForIpId(address ipId) external view returns (uint256);
}
}
27 changes: 19 additions & 8 deletions contracts/lib/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -69,32 +69,43 @@ library Errors {
// LicenseRegistry //
////////////////////////////////////////////////////////////////////////////

/// @notice Error thrown when a policy is already set for an IP ID.
error LicenseRegistry__PolicyAlreadySetForIpId();
error LicenseRegistry__FrameworkNotFound();
error LicenseRegistry__EmptyLicenseUrl();
error LicenseRegistry__ZeroPolicyFramework();
error LicenseRegistry__PolicyAlreadyAdded();
error LicenseRegistry__ParamVerifierLengthMismatch();
error LicenseRegistry__InvalidParamVerifierType();
error LicenseRegistry__PolicyNotFound();
error LicenseRegistry__NotLicensee();
error LicenseRegistry__ParentIdEqualThanChild();
error LicenseRegistry__LicensorDoesntHaveThisPolicy();
error LicenseRegistry__ParamVerifierFailed(uint8 verifierType, address verifier);
error LicenseRegistry__MintLicenseParamFailed();
error LicenseRegistry__LinkParentParamFailed();
error LicenseRegistry__TransferParamFailed();
error LicenseRegistry__InvalidLicensor();
error LicenseRegistry__ParamVerifierAlreadySet();
error LicenseRegistry__CommercialTermInNonCommercialPolicy();
error LicenseRegistry__EmptyParamName();
error LicenseRegistry__UnregisteredFrameworkAddingPolicy();
error LicenseRegistry__UnauthorizedAccess();
error LicenseRegistry__LicensorNotRegistered();

////////////////////////////////////////////////////////////////////////////
// BaseParamVerifier //
// LicenseRegistryAware //
////////////////////////////////////////////////////////////////////////////
error BaseParamVerifier__Unauthorized();

error LicenseRegistryAware__CallerNotLicenseRegistry();

////////////////////////////////////////////////////////////////////////////
// PolicyFramework //
////////////////////////////////////////////////////////////////////////////

error PolicyFramework_FrameworkNotYetRegistered();

////////////////////////////////////////////////////////////////////////////
// DerivativesParamVerifier //
// LicensorApprovalManager //
////////////////////////////////////////////////////////////////////////////
error DerivativesParamVerifier__InvalidDerivativesConfig();
error DerivativesParamVerifier__ZeroShare();
error LicensorApprovalManager__Unauthorized();

////////////////////////////////////////////////////////////////////////////
// Dispute Module //
Expand Down
Loading
Loading