diff --git a/contracts/AccessController.sol b/contracts/AccessController.sol index 81266b613..396ba9ec9 100644 --- a/contracts/AccessController.sol +++ b/contracts/AccessController.sol @@ -45,14 +45,14 @@ contract AccessController is IAccessController, Governable { } /// @inheritdoc IAccessController - function setBatchPermissions(AccessPermission.Permission[] memory permissions) external whenNotPaused { - for (uint256 i = 0; i < permissions.length; ) { + function setBatchPermissions(AccessPermission.Permission[] memory permissions_) external whenNotPaused { + for (uint256 i = 0; i < permissions_.length; ) { setPermission( - permissions[i].ipAccount, - permissions[i].signer, - permissions[i].to, - permissions[i].func, - permissions[i].permission + permissions_[i].ipAccount, + permissions_[i].signer, + permissions_[i].to, + permissions_[i].func, + permissions_[i].permission ); unchecked { i += 1; diff --git a/contracts/interfaces/modules/ITaggingModule.sol b/contracts/interfaces/modules/ITaggingModule.sol index 35cd77027..d786903ec 100644 --- a/contracts/interfaces/modules/ITaggingModule.sol +++ b/contracts/interfaces/modules/ITaggingModule.sol @@ -1,8 +1,52 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.23; -interface ITaggingModule { +import { IModule } from "../../interfaces/modules/base/IModule.sol"; + +/// @title Tagging module interface +interface ITaggingModule is IModule { + /// @notice Emitted when a tag is set for an IP + /// @param tag The tag + /// @param ipId The IP id event TagSet(string tag, address ipId); + /// @notice Emitted when a tag is removed for an IP + /// @param tag The tag + /// @param ipId The IP id event TagRemoved(string tag, address ipId); + + /// @notice Sets a tag for an IP + /// @param tag The tag + /// @param ipId The IP id + /// @return added True if the tag was added + function setTag(string calldata tag, address ipId) external returns (bool added); + + /// @notice Removes a tag for an IP + /// @param tag The tag + /// @param ipId The IP id + /// @return removed True if the tag was removed + function removeTag(string calldata tag, address ipId) external returns (bool removed); + + /// @notice Checks if an IP is tagged with a specific tag + /// @param tag The tag + /// @param ipId The IP id + /// @return True if the IP is tagged with the tag + function isTagged(string calldata tag, address ipId) external view returns (bool); + + /// @notice Gets the total number of tags for an IP + /// @param ipId The IP id + /// @return The total number of tags for the IP + function totalTagsForIp(address ipId) external view returns (uint256); + + /// @notice Gets the tag at a specific index for an IP + /// @param ipId The IP id + /// @param index The index + /// @return The tag at the index + function tagAtIndexForIp(address ipId, uint256 index) external view returns (bytes32); + + /// @notice Gets the tag string at a specific index for an IP + /// @param ipId The IP id + /// @param index The index + /// @return The tag string at the index + function tagStringAtIndexForIp(address ipId, uint256 index) external view returns (string memory); } diff --git a/contracts/interfaces/modules/dispute/IDisputeModule.sol b/contracts/interfaces/modules/dispute/IDisputeModule.sol index 389458226..1983c05d6 100644 --- a/contracts/interfaces/modules/dispute/IDisputeModule.sol +++ b/contracts/interfaces/modules/dispute/IDisputeModule.sol @@ -21,7 +21,7 @@ interface IDisputeModule { /// @notice Event emitted when the base arbitration policy is set /// @param arbitrationPolicy The address of the arbitration policy - event DefaultArbitrationPolicySet(address arbitrationPolicy); + event DefaultArbitrationPolicyUpdated(address arbitrationPolicy); /// @notice Event emitted when an arbitration policy is set for an ipId /// @param ipId The ipId address @@ -64,7 +64,7 @@ interface IDisputeModule { /// @notice Whitelists a dispute tag /// @param tag The dispute tag /// @param allowed Indicates if the dispute tag is whitelisted or not - function whitelistDisputeTags(bytes32 tag, bool allowed) external; + function whitelistDisputeTag(bytes32 tag, bool allowed) external; /// @notice Whitelists an arbitration policy /// @param arbitrationPolicy The address of the arbitration policy diff --git a/contracts/interfaces/modules/licensing/ILicensingModule.sol b/contracts/interfaces/modules/licensing/ILicensingModule.sol index 5d199098b..d2d7fe491 100644 --- a/contracts/interfaces/modules/licensing/ILicensingModule.sol +++ b/contracts/interfaces/modules/licensing/ILicensingModule.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.23; import { Licensing } from "../../../lib/Licensing.sol"; +import { IModule } from "../../modules/base/IModule.sol"; /// @title ILicensingModule /// @notice Interface for the LicensingModule contract, which is the main entry point for the licensing system. @@ -12,7 +13,7 @@ import { Licensing } from "../../../lib/Licensing.sol"; /// - Linking IP to its parent /// - Verifying linking parameters /// - Verifying policy parameters -interface ILicensingModule { +interface ILicensingModule is IModule { /// @notice Emitted when a policy framework is created by registering a policy framework manager /// @param framework The address of the IPolicyFrameworkManager /// @param framework The policy framework data @@ -41,7 +42,7 @@ interface ILicensingModule { /// @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 parentIpIds The ids of the parent IP + /// @param parentIpIds The ids of the parent IPs event IpIdLinkedToParents(address indexed caller, address indexed ipId, address[] parentIpIds); /// @notice Returns the address of the LicenseRegistry diff --git a/contracts/interfaces/modules/royalty/IRoyaltyModule.sol b/contracts/interfaces/modules/royalty/IRoyaltyModule.sol index d6c9f2efb..0c4c9b4da 100644 --- a/contracts/interfaces/modules/royalty/IRoyaltyModule.sol +++ b/contracts/interfaces/modules/royalty/IRoyaltyModule.sol @@ -1,8 +1,10 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.23; +import { IModule } from "../../modules/base/IModule.sol"; + /// @title RoyaltyModule interface -interface IRoyaltyModule { +interface IRoyaltyModule is IModule { /// @notice Event emitted when a royalty policy is whitelisted /// @param royaltyPolicy The address of the royalty policy /// @param allowed Indicates if the royalty policy is whitelisted or not diff --git a/contracts/lib/modules/Module.sol b/contracts/lib/modules/Module.sol index 8dc3dbf8e..ddd3b61fb 100644 --- a/contracts/lib/modules/Module.sol +++ b/contracts/lib/modules/Module.sol @@ -10,3 +10,9 @@ string constant REGISTRATION_MODULE_KEY = "REGISTRATION_MODULE"; // String values for core protocol modules. string constant DISPUTE_MODULE_KEY = "DISPUTE_MODULE"; + +string constant TAGGING_MODULE_KEY = "TAGGING_MODULE"; + +string constant ROYALTY_MODULE_KEY = "ROYALTY_MODULE"; + +string constant LICENSING_MODULE_KEY = "LICENSING_MODULE"; diff --git a/contracts/modules/dispute-module/DisputeModule.sol b/contracts/modules/dispute-module/DisputeModule.sol index 0c8a5a391..dd4b1bb09 100644 --- a/contracts/modules/dispute-module/DisputeModule.sol +++ b/contracts/modules/dispute-module/DisputeModule.sol @@ -66,7 +66,7 @@ contract DisputeModule is IDisputeModule, BaseModule, Governable, ReentrancyGuar /// @notice Whitelists a dispute tag /// @param _tag The dispute tag /// @param _allowed Indicates if the dispute tag is whitelisted or not - function whitelistDisputeTags(bytes32 _tag, bool _allowed) external onlyProtocolAdmin { + function whitelistDisputeTag(bytes32 _tag, bool _allowed) external onlyProtocolAdmin { if (_tag == bytes32(0)) revert Errors.DisputeModule__ZeroDisputeTag(); isWhitelistedDisputeTag[_tag] = _allowed; @@ -108,7 +108,7 @@ contract DisputeModule is IDisputeModule, BaseModule, Governable, ReentrancyGuar baseArbitrationPolicy = _arbitrationPolicy; - emit DefaultArbitrationPolicySet(_arbitrationPolicy); + emit DefaultArbitrationPolicyUpdated(_arbitrationPolicy); } /// @notice Sets the arbitration policy for an ipId diff --git a/contracts/modules/licensing/LicensingModule.sol b/contracts/modules/licensing/LicensingModule.sol index cc76b942c..01864c1c0 100644 --- a/contracts/modules/licensing/LicensingModule.sol +++ b/contracts/modules/licensing/LicensingModule.sol @@ -17,6 +17,7 @@ import { Licensing } from "../../lib/Licensing.sol"; import { IPAccountChecker } from "../../lib/registries/IPAccountChecker.sol"; import { RoyaltyModule } from "../../modules/royalty-module/RoyaltyModule.sol"; import { AccessControlled } from "../../access/AccessControlled.sol"; +import { LICENSING_MODULE_KEY } from "../../lib/modules/Module.sol"; // TODO: consider disabling operators/approvals on creation contract LicensingModule is AccessControlled, ILicensingModule { @@ -36,6 +37,7 @@ contract LicensingModule is AccessControlled, ILicensingModule { RoyaltyModule public immutable ROYALTY_MODULE; ILicenseRegistry public immutable LICENSE_REGISTRY; + string public constant override name = LICENSING_MODULE_KEY; mapping(address framework => bool registered) private _registeredFrameworkManagers; mapping(bytes32 policyHash => uint256 policyId) private _hashedPolicies; mapping(uint256 policyId => Licensing.Policy policyData) private _policies; @@ -379,10 +381,6 @@ contract LicensingModule is AccessControlled, ILicensingModule { return _registeredFrameworkManagers[policyFramework]; } - function name() external pure returns (string memory) { - return "LICENSING_MODULE"; - } - /// Returns amount of distinct licensing policies in LicenseRegistry function totalPolicies() external view returns (uint256) { return _totalPolicies; diff --git a/contracts/modules/royalty-module/RoyaltyModule.sol b/contracts/modules/royalty-module/RoyaltyModule.sol index c1c847dbf..f21c9713e 100644 --- a/contracts/modules/royalty-module/RoyaltyModule.sol +++ b/contracts/modules/royalty-module/RoyaltyModule.sol @@ -7,11 +7,15 @@ import { Governable } from "../../governance/Governable.sol"; import { IRoyaltyModule } from "../../interfaces/modules/royalty/IRoyaltyModule.sol"; import { IRoyaltyPolicy } from "../../interfaces/modules/royalty/policies/IRoyaltyPolicy.sol"; import { Errors } from "../../lib/Errors.sol"; +import { ROYALTY_MODULE_KEY } from "../../lib/modules/Module.sol"; /// @title Story Protocol Royalty Module /// @notice The Story Protocol royalty module allows to set royalty policies an ipId /// and pay royalties as a derivative ip. contract RoyaltyModule is IRoyaltyModule, Governable, ReentrancyGuard { + + string public constant override name = ROYALTY_MODULE_KEY; + /// @notice Licensing module address address public LICENSING_MODULE; diff --git a/contracts/modules/tagging/TaggingModule.sol b/contracts/modules/tagging/TaggingModule.sol index 77745c1d6..e3d0c46d9 100644 --- a/contracts/modules/tagging/TaggingModule.sol +++ b/contracts/modules/tagging/TaggingModule.sol @@ -10,15 +10,16 @@ import { ShortStringOps } from "../../utils/ShortStringOps.sol"; import { Errors } from "../../lib/Errors.sol"; import { IModule } from "../../interfaces/modules/base/IModule.sol"; import { ITaggingModule } from "../../interfaces/modules/ITaggingModule.sol"; +import { TAGGING_MODULE_KEY } from "../../lib/modules/Module.sol"; -contract TaggingModule is IModule, ITaggingModule { +contract TaggingModule is ITaggingModule { using ShortStrings for *; using EnumerableSet for EnumerableSet.Bytes32Set; using EnumerableSet for EnumerableSet.AddressSet; uint256 constant MAX_TAG_PERMISSIONS_AT_ONCE = 300; - string public name = "TaggingModule"; + string public constant override name = TAGGING_MODULE_KEY; mapping(address => EnumerableSet.Bytes32Set) private _tagsForIpIds; diff --git a/test/foundry/modules/dispute/ArbitrationPolicySP.t.sol b/test/foundry/modules/dispute/ArbitrationPolicySP.t.sol index 50731d1f3..5fbb53e1c 100644 --- a/test/foundry/modules/dispute/ArbitrationPolicySP.t.sol +++ b/test/foundry/modules/dispute/ArbitrationPolicySP.t.sol @@ -27,7 +27,7 @@ contract TestArbitrationPolicySP is TestHelper { vm.startPrank(u.admin); // whitelist dispute tag - disputeModule.whitelistDisputeTags("PLAGIARISM", true); + disputeModule.whitelistDisputeTag("PLAGIARISM", true); // whitelist arbitration policy disputeModule.whitelistArbitrationPolicy(address(arbitrationPolicySP), true); diff --git a/test/foundry/modules/dispute/DisputeModule.t.sol b/test/foundry/modules/dispute/DisputeModule.t.sol index 8c93b32f0..9e953ed24 100644 --- a/test/foundry/modules/dispute/DisputeModule.t.sol +++ b/test/foundry/modules/dispute/DisputeModule.t.sol @@ -32,7 +32,7 @@ contract TestDisputeModule is TestHelper { event DisputeJudgementSet(uint256 disputeId, bool decision, bytes data); event DisputeCancelled(uint256 disputeId, bytes data); event DisputeResolved(uint256 disputeId); - event DefaultArbitrationPolicySet(address arbitrationPolicy); + event DefaultArbitrationPolicyUpdated(address arbitrationPolicy); event ArbitrationPolicySet(address ipId, address arbitrationPolicy); address public ipAddr; @@ -44,7 +44,7 @@ contract TestDisputeModule is TestHelper { vm.startPrank(u.admin); // whitelist dispute tag - disputeModule.whitelistDisputeTags("PLAGIARISM", true); + disputeModule.whitelistDisputeTag("PLAGIARISM", true); // whitelist arbitration policy disputeModule.whitelistArbitrationPolicy(address(arbitrationPolicySP), true); @@ -120,18 +120,18 @@ contract TestDisputeModule is TestHelper { vm.stopPrank(); } - function test_DisputeModule_whitelistDisputeTags_revert_ZeroDisputeTag() public { + function test_DisputeModule_whitelistDisputeTag_revert_ZeroDisputeTag() public { vm.startPrank(u.admin); vm.expectRevert(Errors.DisputeModule__ZeroDisputeTag.selector); - disputeModule.whitelistDisputeTags(bytes32(0), true); + disputeModule.whitelistDisputeTag(bytes32(0), true); } - function test_DisputeModule_whitelistDisputeTags() public { + function test_DisputeModule_whitelistDisputeTag() public { vm.startPrank(u.admin); vm.expectEmit(true, true, true, true, address(disputeModule)); emit TagWhitelistUpdated(bytes32("INAPPROPRIATE_CONTENT"), true); - disputeModule.whitelistDisputeTags("INAPPROPRIATE_CONTENT", true); + disputeModule.whitelistDisputeTag("INAPPROPRIATE_CONTENT", true); assertEq(disputeModule.isWhitelistedDisputeTag("INAPPROPRIATE_CONTENT"), true); } @@ -183,7 +183,7 @@ contract TestDisputeModule is TestHelper { function test_DisputeModule_setBaseArbitrationPolicy() public { vm.startPrank(u.admin); vm.expectEmit(true, true, true, true, address(disputeModule)); - emit DefaultArbitrationPolicySet(address(arbitrationPolicySP2)); + emit DefaultArbitrationPolicyUpdated(address(arbitrationPolicySP2)); disputeModule.setBaseArbitrationPolicy(address(arbitrationPolicySP2));