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

Commit

Permalink
Parameters (#31)
Browse files Browse the repository at this point in the history
* added transfer terms, refactored term checking

* add param test

* unused var test

* fix policy needs transfer arguments

* fix tests, addPolicy public only allow new policies

* licenseData not provided when minting, it is a result

* added activation

* wip: license activation

* rolled back license status

* removed activation related code

* stray activation method

* stray event

* stray errors

* fix comment

* fix comment

* WIP

* comment

* fixes

* WIP

* WIP: fix identification of policy set by linking

* refactor to compile

* fix except integration

* feat: integration test fix, remove local vars, add reverts on verification

* fix: verifier interfaces, integration test fix, mock verifier fix, remove local var

* fix: rename contract, add constructor param for mock verifier, formats, more base contract, test fixes

* fix: rename vars and clean stack

* feat: flexible MockParamVerifier, modify integration/unit test runs

* Update contracts/interfaces/licensing/IMintParamVerifier.sol

---------

Co-authored-by: Raul <[email protected]>
Co-authored-by: Jongwon Park <[email protected]>
  • Loading branch information
3 people authored Jan 27, 2024
1 parent 6de2d8b commit e2c1240
Show file tree
Hide file tree
Showing 16 changed files with 742 additions and 407 deletions.
15 changes: 15 additions & 0 deletions contracts/interfaces/licensing/ILinkParamVerifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.23;

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

interface ILinkParamVerifier is IParamVerifier {
function verifyLink(
uint256 licenseId,
address caller,
address ipId,
address parentIpId,
bytes calldata data
) external returns (bool);
}
17 changes: 17 additions & 0 deletions contracts/interfaces/licensing/IMintParamVerifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: UNLICENSED

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

interface IMintParamVerifier is IParamVerifier {
function verifyMint(
address caller,
uint256 policyId,
bool policyAddedByLinking,
address licensor,
address receiver,
uint256 mintAmount,
bytes memory data
) external returns (bool);
}

17 changes: 11 additions & 6 deletions contracts/interfaces/licensing/IParamVerifier.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.20;
pragma solidity ^0.8.23;

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

interface IParamVerifier is IERC165 {
function name() external view returns (bytes32);

function nameString() external view returns (string memory);

interface IParamVerifier {
function verifyMinting(address caller, uint256 amount, bytes memory data) external returns (bool);
function verifyTransfer(address caller, uint256 amount, bytes memory data) external returns (bool);
function verifyLinkParent(address caller, bytes memory data) external returns (bool);
function json() external view returns (string memory);

function allowsOtherPolicyOnSameIp(bytes memory data) external view returns (bool);
}
15 changes: 15 additions & 0 deletions contracts/interfaces/licensing/ITransferParamVerifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.23;

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

interface ITransferParamVerifier is IParamVerifier {
function verifyTransfer(
uint256 licenseId,
address from,
address to,
uint256 amount,
bytes memory data
) external returns (bool);
}
21 changes: 15 additions & 6 deletions contracts/interfaces/registries/ILicenseRegistry.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.23;

import { Licensing } from "contracts/lib/Licensing.sol";
Expand All @@ -12,7 +12,13 @@ interface ILicenseRegistry {

event PolicyCreated(address indexed creator, uint256 indexed policyId, Licensing.Policy policy);

event PolicyAddedToIpId(address indexed caller, address indexed ipId, uint256 indexed policyId, bool setByLinking);
event PolicyAddedToIpId(
address indexed caller,
address indexed ipId,
uint256 indexed policyId,
uint256 index,
bool setByLinking
);

event LicenseMinted(
address indexed creator,
Expand All @@ -39,7 +45,7 @@ interface ILicenseRegistry {

function mintLicense(
uint256 policyId,
address[] calldata licensorIpIds,
address licensorIpId,
uint256 amount,
address receiver
) external returns (uint256 licenseId);
Expand All @@ -52,10 +58,9 @@ interface ILicenseRegistry {

function totalFrameworks() external view returns (uint256);

function frameworkParams(uint256 frameworkId, Licensing.ParamVerifierType pvt) external view returns (Licensing.Parameter[] memory);
function frameworkParam(uint256 frameworkId, string calldata name) external view returns (Licensing.Parameter memory);
function frameworkUrl(uint256 frameworkId) external view returns (string memory);


function totalPolicies() external view returns (uint256);

function policy(uint256 policyId) external view returns (Licensing.Policy memory pol);
Expand All @@ -72,10 +77,14 @@ interface ILicenseRegistry {

function policyForIpAtIndex(address ipId, uint256 index) external view returns (Licensing.Policy memory);

function isPolicyIdAtIndexSetByLinking(address ipId, uint256 index) external view returns (bool);
function indexOfPolicyForIp(address ipId, uint256 policyId) external view returns (uint256 index);

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

function isLicensee(uint256 licenseId, address holder) external view returns (bool);

function licensorIpId(uint256 licenseId) external view returns (address);
function license(uint256 licenseId) external view returns (Licensing.License memory);
function isParent(address parentIpId, address childIpId) external view returns (bool);

function parentIpIds(address ipId) external view returns (address[] memory);
Expand Down
13 changes: 12 additions & 1 deletion contracts/lib/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,19 @@ library Errors {
error LicenseRegistry__LicensorDoesntHaveThisPolicy();
error LicenseRegistry__ParamVerifierFailed(uint8 verifierType, address verifier);
error LicenseRegistry__LinkParentParamFailed();
error LicenseRegistry__LicenseMustHaveLicensors();
error LicenseRegistry__InvalidLicensor();
error LicenseRegistry__ParamVerifierAlreadySet();

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

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

////////////////////////////////////////////////////////////////////////////
// Dispute Module //
Expand Down
57 changes: 18 additions & 39 deletions contracts/lib/Licensing.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// SPDX-License-Identifier: MIT
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.20;
import { IParamVerifier } from "../interfaces/licensing/IParamVerifier.sol";
import { Errors } from "./Errors.sol";

library Licensing {


/// Identifies a license parameter (term) from a license framework
struct Parameter {
/// Contract that must check if the condition of the paremeter is set
Expand All @@ -27,61 +28,39 @@ library Licensing {
/// To be valid in Story Protocol, the parameters described in the text must express default values
/// corresponding to those of each Parameter struct
struct Framework {
/// @notice Stores the parameters that need to be verified in each moment of the license lifetime
/// ParamVerifierType.Mint --> These parameters need to be verified when minting a license
/// ParamVerifierType.LinkParent --> Verified before the owner of a license links to a parent ipId/policy,
/// burning the license and setting the policy for the ipId.
/// ParamVerifierType.Transfer -> verified when transfering NFT
mapping(ParamVerifierType => Parameter[]) parameters;
/// @notice Stores the parameters that need to be verified in each moment of the licensing lifetime
mapping(bytes32 => Parameter) parameters;
/// @notice URL to the file containing the legal text for the license agreement
string licenseUrl;
}

// Needed because Solidity doesn't support passing nested struct arrays to storage
struct FrameworkCreationParams {
IParamVerifier[] mintingVerifiers;
bytes[] mintingDefaultValues;
IParamVerifier[] linkParentVerifiers;
bytes[] linkParentDefaultValues;
IParamVerifier[] transferVerifiers;
bytes[] transferDefaultValues;
IParamVerifier[] parameters;
bytes[] defaultValues;
string licenseUrl;
}
/// A particular configuration of a Licensing Framework, setting (or not) values fo the licensing

/// A particular configuration of a Licensing Framework, setting (or not) values for the licensing
/// terms (parameters) of the framework.
/// The lengths of the param value arrays must correspond to the Parameter[] of the framework.
struct Policy {
/// True if the policy accepts commercial terms
bool commercialUse;
/// True if the policy accepts derivative-related terms
bool derivatives;
/// Id of a Licensing Framework
uint256 frameworkId;
/// Array with values for parameters verifying conditions to mint a license. Empty bytes for index if
/// this policy wants to use the default value for the paremeter.
bytes[] mintingParamValues;
/// Array with values for parameters verifying conditions to link a license to a parent. Empty bytes for index if
/// this policy wants to use the default value for the paremeter.
bytes[] linkParentParamValues;
/// Array with values for parameters verifying conditions to transfer a license. Empty bytes for index if
/// this policy wants to use the default value for the paremeter.
bytes[] transferParamValues;
}

function getValues(Policy memory policy, ParamVerifierType pvt) internal returns(bytes[] memory) {
if (pvt == ParamVerifierType.Mint) {
return policy.mintingParamValues;
} else if (pvt == ParamVerifierType.LinkParent) {
return policy.linkParentParamValues;
} else if (pvt == ParamVerifierType.Transfer) {
return policy.transferParamValues;
} else {
revert Errors.LicenseRegistry__InvalidParamVerifierType();
}
/// Names of the parameters of the framework. Must be the same that IParamVerifier.name() returns
bytes32[] paramNames;
/// Values for the parameters of the framework. Index must correspond to paramNames[]
bytes[] paramValues;
}

/// Data that define a License Agreement NFT
struct License {
/// the id for the Policy this License will set to the desired derivative IP after being burned.
uint256 policyId;
/// Ids for the licensors, meaning the Ip Ids of the parents of the derivative to be created
address[] licensorIpIds;
/// Id for the licensor of the Ip Id
address licensorIpId;
}
}
56 changes: 56 additions & 0 deletions contracts/modules/licensing/parameters/BaseParamVerifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: UNLICENSED
// See https://github.com/storyprotocol/protocol-contracts/blob/main/StoryProtocol-AlphaTestingAgreement-17942166.3.pdf
pragma solidity ^0.8.23;

// contracts
import { ILinkParamVerifier } from "contracts/interfaces/licensing/ILinkParamVerifier.sol";
import { IMintParamVerifier } from "contracts/interfaces/licensing/IMintParamVerifier.sol";
import { IParamVerifier } from "contracts/interfaces/licensing/IParamVerifier.sol";
import { ITransferParamVerifier } from "contracts/interfaces/licensing/ITransferParamVerifier.sol";
import { Errors } from "contracts/lib/Errors.sol";
import { LicenseRegistry } from "contracts/registries/LicenseRegistry.sol";
import { ShortStringOps } from "contracts/utils/ShortStringOps.sol";

abstract contract BaseParamVerifier is IParamVerifier {
// /// @notice Gets the protocol-wide module access controller.
// IAccessController public immutable ACCESS_CONTROLLER;

// /// @notice Gets the protocol-wide IP account registry.
// IPAccountRegistry public immutable IP_ACCOUNT_REGISTRY;

// /// @notice Gets the protocol-wide IP record registry.
// IPRecordRegistry public immutable IP_RECORD_REGISTRY;

/// @notice Gets the protocol-wide license registry.
LicenseRegistry public immutable LICENSE_REGISTRY;

string internal NAME;

/// @notice Initializes the base module contract.
/// @param licenseRegistry The address of the license registry.
constructor(address licenseRegistry, string memory name_) {
LICENSE_REGISTRY = LicenseRegistry(licenseRegistry);
NAME = name_;
}

/// @notice Modifier for authorizing the calling entity.
modifier onlyLicenseRegistry() {
if (msg.sender != address(LICENSE_REGISTRY)) {
revert Errors.BaseParamVerifier__Unauthorized();
}
_;
}

function name() external view override returns (bytes32) {
return ShortStringOps.stringToBytes32(NAME);
}

function nameString() external view override returns (string memory) {
return NAME;
}

// TODO: implement flexible json()
function json() external view returns (string memory) {
return "";
}
}
Loading

0 comments on commit e2c1240

Please sign in to comment.