From b4741d9c450e8e5203eb7e8cb45de28c9bf0d6f5 Mon Sep 17 00:00:00 2001 From: Jongwon Park Date: Tue, 16 Apr 2024 02:54:21 -0500 Subject: [PATCH] Remove & Rename Errors and Correct Names (#112) * nit: Remove unused code in library * fix: Error typo & remove unused errors, variable name change * fix: more error comment and name correction * nit: comments * nit: Error comments * refactor: ShortStringOps directory --- contracts/IPAccountImpl.sol | 2 +- contracts/access/AccessController.sol | 5 +- .../registries/ILicenseRegistry.sol | 2 - contracts/lib/Errors.sol | 469 ++++++++++++------ contracts/lib/PILicenseTemplateErrors.sol | 39 +- contracts/lib/ShortStringOps.sol | 16 + contracts/modules/dispute/DisputeModule.sol | 18 +- .../modules/licensing/PILicenseTemplate.sol | 3 +- contracts/registries/IPAccountRegistry.sol | 2 +- contracts/utils/ShortStringOps.sol | 53 -- .../modules/dispute/DisputeModule.t.sol | 2 +- 11 files changed, 364 insertions(+), 247 deletions(-) create mode 100644 contracts/lib/ShortStringOps.sol delete mode 100644 contracts/utils/ShortStringOps.sol diff --git a/contracts/IPAccountImpl.sol b/contracts/IPAccountImpl.sol index 62e4cd195..1f2921cca 100644 --- a/contracts/IPAccountImpl.sol +++ b/contracts/IPAccountImpl.sol @@ -37,7 +37,7 @@ contract IPAccountImpl is IPAccountStorage, IIPAccount { address licenseRegistry, address moduleRegistry ) IPAccountStorage(ipAssetRegistry, licenseRegistry, moduleRegistry) { - if (accessController == address(0)) revert Errors.IPAccount__InvalidAccessController(); + if (accessController == address(0)) revert Errors.IPAccount__ZeroAccessController(); ACCESS_CONTROLLER = accessController; } diff --git a/contracts/access/AccessController.sol b/contracts/access/AccessController.sol index 764dd91cc..5df1151ec 100644 --- a/contracts/access/AccessController.sol +++ b/contracts/access/AccessController.sol @@ -65,7 +65,7 @@ contract AccessController is IAccessController, ProtocolPausableUpgradeable, UUP } /// @notice Sets the addresses of the IP account registry and the module registry - /// @dev TODO: figure out how to set these addresses in the constructor to make them immutable + /// @dev TODO: Set these addresses in the constructor to make them immutable /// @param ipAccountRegistry address of the IP account registry /// @param moduleRegistry address of the module registry function setAddresses(address ipAccountRegistry, address moduleRegistry) external restricted { @@ -75,10 +75,9 @@ contract AccessController is IAccessController, ProtocolPausableUpgradeable, UUP } /// @notice Sets a batch of permissions in a single transaction. - /// @dev This function allows setting multiple permissions at once. Pausable. + /// @dev This function allows setting multiple permissions at once. Pausable via setPermission. /// @param permissions An array of `Permission` structs, each representing the permission to be set. function setBatchPermissions(AccessPermission.Permission[] memory permissions) external { - // TODO: removed pause. for (uint256 i = 0; i < permissions.length; ) { setPermission( permissions[i].ipAccount, diff --git a/contracts/interfaces/registries/ILicenseRegistry.sol b/contracts/interfaces/registries/ILicenseRegistry.sol index 6dab7bcb0..4ed4278c2 100644 --- a/contracts/interfaces/registries/ILicenseRegistry.sol +++ b/contracts/interfaces/registries/ILicenseRegistry.sol @@ -64,8 +64,6 @@ interface ILicenseRegistry { /// @return Whether the IP has derivative IPs. function hasDerivativeIps(address ipId) external view returns (bool); - // TODO: getDerivativeIpCount - /// @notice Verifies the minting of a license token. /// @param licensorIpId The address of the licensor IP. /// @param licenseTemplate The address of the license template where the license terms are defined. diff --git a/contracts/lib/Errors.sol b/contracts/lib/Errors.sol index 62e94118e..f74f4c9c9 100644 --- a/contracts/lib/Errors.sol +++ b/contracts/lib/Errors.sol @@ -5,62 +5,48 @@ pragma solidity 0.8.23; /// @notice Library for all Story Protocol contract errors. library Errors { //////////////////////////////////////////////////////////////////////////// - // IPAccount // + // IP Account // //////////////////////////////////////////////////////////////////////////// + + /// @notice Zero address provided for Access Controller. + error IPAccount__ZeroAccessController(); + + /// @notice Invalid signer provided. error IPAccount__InvalidSigner(); + + /// @notice Invalid signature provided, must be an EIP-712 signature. error IPAccount__InvalidSignature(); + + /// @notice Signature is expired. error IPAccount__ExpiredSignature(); + + /// @notice Provided calldata is invalid. error IPAccount__InvalidCalldata(); - error IPAccount__InvalidAccessController(); //////////////////////////////////////////////////////////////////////////// - // IPAccountStorage // + // IP Account Storage // //////////////////////////////////////////////////////////////////////////// + + /// @notice Caller writing to IP Account storage is not a registered module. error IPAccountStorage__NotRegisteredModule(address module); //////////////////////////////////////////////////////////////////////////// - // Module // + // IP Account Registry // //////////////////////////////////////////////////////////////////////////// - /// @notice The caller is not allowed to call the provided module. - error Module_Unauthorized(); + /// @notice Zero address provided for IP Account implementation. + error IPAccountRegistry_ZeroIpAccountImpl(); //////////////////////////////////////////////////////////////////////////// - // IPAccountRegistry // + // IP Asset Registry // //////////////////////////////////////////////////////////////////////////// - error IPAccountRegistry_InvalidIpAccountImpl(); - //////////////////////////////////////////////////////////////////////////// - // IPAssetRegistry // - //////////////////////////////////////////////////////////////////////////// - - /// @notice zero address provided for access manager in initializer. + /// @notice Zero address provided for Access Manager in initializer. error IPAssetRegistry__ZeroAccessManager(); /// @notice The IP asset has already been registered. error IPAssetRegistry__AlreadyRegistered(); - /// @notice The IP account has already been created. - error IPAssetRegistry__IPAccountAlreadyCreated(); - - /// @notice The IP asset has not yet been registered. - error IPAssetRegistry__NotYetRegistered(); - - /// @notice The IP asset registrant is not authorized. - error IPAssetRegistry__RegistrantUnauthorized(); - - /// @notice The specified IP resolver is not valid. - error IPAssetRegistry__ResolverInvalid(); - - /// @notice Caller not authorized to perform the IP registry function call. - error IPAssetRegistry__Unauthorized(); - - /// @notice The deployed address of account doesn't match with IP ID. - error IPAssetRegistry__InvalidAccount(); - - /// @notice The metadata provider is not valid. - error IPAssetRegistry__InvalidMetadataProvider(); - /// @notice The NFT token contract is not valid ERC721 contract. error IPAssetRegistry__UnsupportedIERC721(address contractAddress); @@ -71,153 +57,153 @@ library Errors { error IPAssetRegistry__InvalidToken(address contractAddress, uint256 tokenId); //////////////////////////////////////////////////////////////////////////// - // IPResolver /// + // License Registry // //////////////////////////////////////////////////////////////////////////// - /// @notice The targeted IP does not yet have an IP account. - error IPResolver_InvalidIP(); - - /// @notice Caller not authorized to perform the IP resolver function call. - error IPResolver_Unauthorized(); - - //////////////////////////////////////////////////////////////////////////// - // Metadata Provider /// - //////////////////////////////////////////////////////////////////////////// + /// @notice Zero address provided for Access Manager in initializer. + error LicenseRegistry__ZeroAccessManager(); - /// @notice Provided hash metadata is not valid. - error MetadataProvider__HashInvalid(); + /// @notice Zero address provided for Licensing Module. + error LicenseRegistry__ZeroLicensingModule(); - /// @notice The caller is not the authorized IP asset owner. - error MetadataProvider__IPAssetOwnerInvalid(); + /// @notice Zero address provided for Dispute Module. + error LicenseRegistry__ZeroDisputeModule(); - /// @notice Provided hash metadata is not valid. - error MetadataProvider__NameInvalid(); + /// @notice Caller is not the Licensing Module. + error LicenseRegistry__CallerNotLicensingModule(); - /// @notice The new metadata provider is not compatible with the old provider. - error MetadataProvider__MetadataNotCompatible(); + /// @notice Emitted when trying to transfer a license that is not transferable (by policy) + error LicenseRegistry__NotTransferable(); - /// @notice Provided registrant metadata is not valid. - error MetadataProvider__RegistrantInvalid(); + /// @notice License Template is not registered in the License Registry. + error LicenseRegistry__UnregisteredLicenseTemplate(address licenseTemplate); - /// @notice Provided registration date is not valid. - error MetadataProvider__RegistrationDateInvalid(); + /// @notice License Terms or License Template not found. + error LicenseRegistry__LicenseTermsNotExists(address licenseTemplate, uint256 licenseTermsId); - /// @notice Caller does not access to set metadata storage for the provider. - error MetadataProvider__Unauthorized(); + /// @notice Licensor IP does not have the provided license terms attached. + error LicenseRegistry__LicensorIpHasNoLicenseTerms(address ipId, address licenseTemplate, uint256 licenseTermsId); - /// @notice A metadata provider upgrade is not currently available. - error MetadataProvider__UpgradeUnavailable(); + /// @notice Invalid License Template address provided. + error LicenseRegistry__NotLicenseTemplate(address licenseTemplate); - /// @notice The upgrade provider is not valid. - error MetadataProvider__UpgradeProviderInvalid(); + /// @notice IP is expired. + error LicenseRegistry__IpExpired(address ipId); - /// @notice Provided metadata URI is not valid. - error MetadataProvider__URIInvalid(); + /// @notice Parent IP is expired. + error LicenseRegistry__ParentIpExpired(address ipId); - //////////////////////////////////////////////////////////////////////////// - // LicenseRegistry // - //////////////////////////////////////////////////////////////////////////// + /// @notice Parent IP is dispute tagged. + error LicenseRegistry__ParentIpTagged(address ipId); - error LicenseRegistry__ZeroAccessManager(); - error LicenseRegistry__CallerNotLicensingModule(); - error LicenseRegistry__ZeroLicensingModule(); - error LicensingModule__CallerNotLicenseRegistry(); - /// @notice emitted when trying to transfer a license that is not transferable (by policy) - error LicenseRegistry__NotTransferable(); - /// @notice emitted on constructor if dispute module is not set - error LicenseRegistry__ZeroDisputeModule(); - error LicenseRegistry__UnregisteredLicenseTemplate(address licenseTemplate); - error LicenseRegistry__NotLicenseTemplate(address licenseTemplate); - error LicenseRegistry__IpExpired(address ipId); - error LicenseRegistry__ParentIpExpired(address ipId); - error LicenseRegistry__LicenseTermsNotExists(address licenseTemplate, uint256 licenseTermsId); + /// @notice Parent IP does not have the provided license terms attached. error LicenseRegistry__ParentIpHasNoLicenseTerms(address ipId, uint256 licenseTermsId); - error LicenseRegistry__LicensorIpHasNoLicenseTerms(address ipId, address licenseTemplate, uint256 licenseTermsId); + + /// @notice Empty Parent IP list provided. error LicenseRegistry__NoParentIp(); + + /// @notice Provided derivative IP already has license terms attached. error LicenseRegistry__DerivativeIpAlreadyHasLicense(address childIpId); + + /// @notice Provided derivative IP is already registered. error LicenseRegistry__DerivativeAlreadyRegistered(address childIpId); - error LicenseRegistry__ParentIpTagged(address ipId); + + /// @notice Provided derivative IP is the same as the parent IP. error LicenseRegistry__DerivativeIsParent(address ipId); + + /// @notice Provided license template does not match the parent IP's current license template. error LicenseRegistry__ParentIpUnmatchedLicenseTemplate(address ipId, address licenseTemplate); + + /// @notice Index out of bounds. error LicenseRegistry__IndexOutOfBounds(address ipId, uint256 index, uint256 length); + + /// @notice Provided license template and terms ID is already attached to IP. error LicenseRegistry__LicenseTermsAlreadyAttached(address ipId, address licenseTemplate, uint256 licenseTermsId); + + /// @notice Provided license template does not match the IP's current license template. error LicenseRegistry__UnmatchedLicenseTemplate(address ipId, address licenseTemplate, address newLicenseTemplate); + + /// @notice Provided license template and terms ID is a duplicate. error LicenseRegistry__DuplicateLicense(address ipId, address licenseTemplate, uint256 licenseTermsId); + //////////////////////////////////////////////////////////////////////////// - // LicenseToken // + // License Token // //////////////////////////////////////////////////////////////////////////// - error LicenseToken__CallerNotLicensingModule(); + + /// @notice Zero address provided for Access Manager in initializer. + error LicenseToken__ZeroAccessManager(); + + /// @notice Zero address provided for Licensing Module. error LicenseToken__ZeroLicensingModule(); + + /// @notice Zero address provided for Dispute Module. error LicenseToken__ZeroDisputeModule(); - error LicenseToken__ZeroAccessManager(); + + /// @notice Caller is not the Licensing Module. + error LicenseToken__CallerNotLicensingModule(); + + /// @notice License token is revoked. error LicenseToken__RevokedLicense(uint256 tokenId); + + /// @notice License token is not transferable. error LicenseToken__NotTransferable(); + + /// @notice License token is expired. error LicenseToken__LicenseTokenExpired(uint256 tokenId, uint256 expiredAt, uint256 currentTimestamp); + + /// @notice License token is not owned by the caller. error LicenseToken__NotLicenseTokenOwner(uint256 tokenId, address iPowner, address tokenOwner); + + /// @notice All license tokens must be from the same license template. error LicenseToken__AllLicenseTokensMustFromSameLicenseTemplate( address licenseTemplate, address anotherLicenseTemplate ); + //////////////////////////////////////////////////////////////////////////// - // LicensingModule // + // Licensing Module // //////////////////////////////////////////////////////////////////////////// + /// @notice Zero address provided for Access Manager in initializer. error LicensingModule__ZeroAccessManager(); - error LicensingModule__IpAlreadyLinked(); - error LicensingModule__PolicyAlreadySetForIpId(); - error LicensingModule__FrameworkNotFound(); - error LicensingModule__EmptyLicenseUrl(); - error LicensingModule__InvalidPolicyFramework(); - error LicensingModule__ParamVerifierLengthMismatch(); - error LicensingModule__PolicyNotFound(); - error LicensingModule__NotLicensee(); - error LicensingModule__ParentIdEqualThanChild(); - error LicensingModule__LicensorDoesntHaveThisPolicy(); - error LicensingModule__MintLicenseParamFailed(); - error LicensingModule__LinkParentParamFailed(); - error LicensingModule__TransferParamFailed(); - error LicensingModule__InvalidLicensor(); - error LicensingModule__ParamVerifierAlreadySet(); - error LicensingModule__CommercialTermInNonCommercialPolicy(); - error LicensingModule__EmptyParamName(); - error LicensingModule__UnregisteredFrameworkAddingPolicy(); - error LicensingModule__UnauthorizedAccess(); - error LicensingModule__LicensorNotRegistered(); - error LicensingModule__CallerNotLicensorAndPolicyNotSet(); - error LicensingModule__DerivativesCannotAddPolicy(); - error LicensingModule__IncompatibleRoyaltyPolicyAddress(); - error LicensingModule__IncompatibleRoyaltyPolicyDerivativeRevShare(); - error LicensingModule__IncompatibleLicensorRoyaltyDerivativeRevShare(); - error LicensingModule__DerivativeRevShareSumExceedsMaxRNFTSupply(); - error LicensingModule__MismatchBetweenRoyaltyPolicy(); - error LicensingModule__RegisterPolicyFrameworkMismatch(); - error LicensingModule__RoyaltyPolicyNotWhitelisted(); - error LicensingModule__MintingFeeTokenNotWhitelisted(); + + /// @notice Receiver is zero address. error LicensingModule__ReceiverZeroAddress(); + + /// @notice Mint amount is zero. error LicensingModule__MintAmountZero(); - /// @notice emitted when trying to interact with an IP that has been disputed in the DisputeModule + + /// @notice IP is dispute tagged. error LicensingModule__DisputedIpId(); - /// @notice emitted when linking a license from a licensor that has been disputed in the DisputeModule - error LicensingModule__LinkingRevokedLicense(); + + /// @notice License template and terms ID is not found. error LicensingModule__LicenseTermsNotFound(address licenseTemplate, uint256 licenseTermsId); + + /// @notice Derivative IP cannot add license terms. error LicensingModule__DerivativesCannotAddLicenseTerms(); - error LicensingModule__CallerNotLicensorAndIpHasNotAttachedLicenseTerms( - address caller, - address licensorIpId, - address licenseTemplate, - uint256 licenseTermsId - ); + + /// @notice Receiver check failed. error LicensingModule__ReceiverCheckFailed(address receiver); - error LicensingModule__DerivativeAlreadyRegistered(); + + /// @notice IP list and license terms list length mismatch. error LicensingModule__LicenseTermsLengthMismatch(uint256 ipLength, uint256 licenseTermsLength); + + /// @notice Parent IP list is empty. error LicensingModule__NoParentIp(); - error LicensingModule__DerivativeIsParent(); - error LicensingModule__ParentIpHasNoLicenseTerms(address ipId); - error LicensingModule__DerivativeAlreadyHasLicenseTerms(address ipId); + + /// @notice Incompatible royalty policy. error LicensingModule__IncompatibleRoyaltyPolicy(address royaltyPolicy, address anotherRoyaltyPolicy); + + /// @notice License template and terms are not compatible for the derivative IP. error LicensingModule__LicenseNotCompatibleForDerivative(address childIpId); + + /// @notice License token list is empty. error LicensingModule__NoLicenseToken(); + + /// @notice License tokens are not compatible for the derivative IP. error LicensingModule__LicenseTokenNotCompatibleForDerivative(address childIpId, uint256[] licenseTokenIds); + + /// @notice License template denied minting license token during the verification stage. error LicensingModule__LicenseDenyMintLicenseToken( address licenseTemplate, uint256 licenseTermsId, @@ -225,143 +211,300 @@ library Errors { ); //////////////////////////////////////////////////////////////////////////// - // PILicenseTemplate // + // Dispute Module // //////////////////////////////////////////////////////////////////////////// - error PILicenseTemplate__ZeroAccessManager(); + /// @notice Zero address provided for Access Manager in initializer. + error DisputeModule__ZeroAccessManager(); - //////////////////////////////////////////////////////////////////////////// - // LicensorApprovalChecker // - //////////////////////////////////////////////////////////////////////////// - error LicensorApprovalChecker__Unauthorized(); + /// @notice Zero address provided for License Registry. + error DisputeModule__ZeroLicenseRegistry(); - //////////////////////////////////////////////////////////////////////////// - // Dispute Module // - //////////////////////////////////////////////////////////////////////////// + /// @notice Zero address provided for IP Asset Registry. + error DisputeModule__ZeroIPAssetRegistry(); + + /// @notice Zero address provided for Access Controller. + error DisputeModule__ZeroAccessController(); + /// @notice Zero address provided for Arbitration Policy. error DisputeModule__ZeroArbitrationPolicy(); + + /// @notice Zero address provided for Arbitration Relayer. error DisputeModule__ZeroArbitrationRelayer(); + + /// @notice Zero bytes provided for Dispute Tag. error DisputeModule__ZeroDisputeTag(); + + /// @notice Zero bytes provided for Dispute Evidence. error DisputeModule__ZeroLinkToDisputeEvidence(); + + /// @notice Not a whitelisted arbitration policy. error DisputeModule__NotWhitelistedArbitrationPolicy(); - error DisputeModule__NotWhitelistedDisputeTag(); + + /// @notice Not a whitelisted arbitration relayer. error DisputeModule__NotWhitelistedArbitrationRelayer(); + + /// @notice Not a whitelisted dispute tag. + error DisputeModule__NotWhitelistedDisputeTag(); + + /// @notice Not the dispute initiator. error DisputeModule__NotDisputeInitiator(); + + /// @notice Not in dispute state, the dispute is not IN_DISPUTE. error DisputeModule__NotInDisputeState(); + + /// @notice Not able to resolve a dispute, either the dispute is IN_DISPUTE or empty. error DisputeModule__NotAbleToResolve(); + + /// @notice Not a registered IP. error DisputeModule__NotRegisteredIpId(); + + /// @notice Provided parent IP and the parent dispute's target IP is different. error DisputeModule__ParentIpIdMismatch(); + + /// @notice Provided parent dispute's target IP is not dispute tagged. error DisputeModule__ParentNotTagged(); + + /// @notice Provided parent dispute's target IP is not the derivative IP's parent. error DisputeModule__NotDerivative(); + + /// @notice Provided parent dispute has not been resolved. error DisputeModule__ParentDisputeNotResolved(); - error DisputeModule__ZeroLicenseRegistry(); - error DisputeModule__ZeroAssetRegistry(); - error DisputeModule__ZeroController(); - error DisputeModule__ZeroAccessManager(); //////////////////////////////////////////////////////////////////////////// // ArbitrationPolicy SP // //////////////////////////////////////////////////////////////////////////// + /// @notice Zero address provided for Access Manager in initializer. + error ArbitrationPolicySP__ZeroAccessManager(); + + /// @notice Zero address provided for Dispute Module. error ArbitrationPolicySP__ZeroDisputeModule(); + + /// @notice Zero address provided for Payment Token. error ArbitrationPolicySP__ZeroPaymentToken(); + + /// @notice Caller is not the Dispute Module. error ArbitrationPolicySP__NotDisputeModule(); - error ArbitrationPolicySP__ZeroAccessManager(); //////////////////////////////////////////////////////////////////////////// // Royalty Module // //////////////////////////////////////////////////////////////////////////// + /// @notice Zero address provided for Access Manager in initializer. + error RoyaltyModule__ZeroAccessManager(); + + /// @notice Zero address provided for Dispute Module. + error RoyaltyModule__ZeroDisputeModule(); + + /// @notice Zero address provided for License Registry. + error RoyaltyModule__ZeroLicenseRegistry(); + + /// @notice Zero address provided for Licensing Module. + error RoyaltyModule__ZeroLicensingModule(); + + /// @notice Zero address provided for Royalty Policy. error RoyaltyModule__ZeroRoyaltyPolicy(); - error RoyaltyModule__NotWhitelistedRoyaltyPolicy(); + + /// @notice Zero address provided for Royalty Token. error RoyaltyModule__ZeroRoyaltyToken(); + + /// @notice Not a whitelisted royalty policy. + error RoyaltyModule__NotWhitelistedRoyaltyPolicy(); + + /// @notice Not a whitelisted royalty token. error RoyaltyModule__NotWhitelistedRoyaltyToken(); + + /// @notice Royalty policy for IP is unset. error RoyaltyModule__NoRoyaltyPolicySet(); + + /// @notice Royalty policy between IPs are incompatible (different). error RoyaltyModule__IncompatibleRoyaltyPolicy(); + + /// @notice Caller is unauthorized. error RoyaltyModule__NotAllowedCaller(); - error RoyaltyModule__ZeroLicensingModule(); + + /// @notice IP can only mint licenses of selected royalty policy. error RoyaltyModule__CanOnlyMintSelectedPolicy(); + + /// @notice Parent IP list for linking is empty. error RoyaltyModule__NoParentsOnLinking(); - error RoyaltyModule__ZeroDisputeModule(); - error RoyaltyModule__ZeroLicenseRegistry(); + + /// @notice IP is expired. error RoyaltyModule__IpIsExpired(); + + /// @notice IP is dipute tagged. error RoyaltyModule__IpIsTagged(); - error RoyaltyModule__ZeroAccessManager(); + //////////////////////////////////////////////////////////////////////////// + // Royalty Policy LAP // + //////////////////////////////////////////////////////////////////////////// + + /// @notice Zero address provided for Access Manager in initializer. + error RoyaltyPolicyLAP__ZeroAccessManager(); + + /// @notice Zero address provided for IP Royalty Vault Beacon. + error RoyaltyPolicyLAP__ZeroIpRoyaltyVaultBeacon(); + + /// @notice Zero address provided for Royalty Module. error RoyaltyPolicyLAP__ZeroRoyaltyModule(); - error RoyaltyPolicyLAP__ZeroLiquidSplitFactory(); - error RoyaltyPolicyLAP__ZeroLiquidSplitMain(); - error RoyaltyPolicyLAP__NotRoyaltyModule(); + + /// @notice Zero address provided for Licensing Module. error RoyaltyPolicyLAP__ZeroLicensingModule(); + + /// @notice Caller is not the Royalty Module. + error RoyaltyPolicyLAP__NotRoyaltyModule(); + + /// @notice Size of parent IP list is above the LAP royalty policy limit. error RoyaltyPolicyLAP__AboveParentLimit(); + + /// @notice Amount of ancestors for derivative IP is above the LAP royalty policy limit. error RoyaltyPolicyLAP__AboveAncestorsLimit(); + + /// @notice Total royalty stack exceeds the protocol limit. error RoyaltyPolicyLAP__AboveRoyaltyStackLimit(); + + /// @notice Size of parent royalties list and parent IP list mismatch. error RoyaltyPolicyLAP__InvalidParentRoyaltiesLength(); - error RoyaltyPolicyLAP__ImplementationAlreadySet(); - error RoyaltyPolicyLAP__ZeroAncestorsVaultImpl(); - error RoyaltyPolicyLAP__NotFullOwnership(); + + /// @notice IP cannot be linked to a parent, because it is either already linked to parents or derivatives (root). error RoyaltyPolicyLAP__UnlinkableToParents(); + + /// @notice Policy is already initialized and IP is at the ancestors limit, so it can't mint more licenses. error RoyaltyPolicyLAP__LastPositionNotAbleToMintLicense(); - error RoyaltyPolicyLAP__ZeroIpRoyaltyVaultBeacon(); - error RoyaltyPolicyLAP__ZeroAccessManager(); + //////////////////////////////////////////////////////////////////////////// + // IP Royalty Vault // + //////////////////////////////////////////////////////////////////////////// + + /// @notice Zero address provided for Royalty Policy LAP. error IpRoyaltyVault__ZeroRoyaltyPolicyLAP(); + + /// @notice Zero address provided for Dispute Module. + error IpRoyaltyVault__ZeroDisputeModule(); + + /// @notice Caller is not the Royalty Policy LAP. error IpRoyaltyVault__NotRoyaltyPolicyLAP(); + + /// @notice Snapshot interval is too short, wait for the interval to pass for the next snapshot. error IpRoyaltyVault__SnapshotIntervalTooShort(); + + /// @notice Royalty Tokens is already claimed. error IpRoyaltyVault__AlreadyClaimed(); + + /// @notice Royalty Tokens claimer is not an ancestor of derivative IP. error IpRoyaltyVault__ClaimerNotAnAncestor(); + + /// @notice IP is dispute tagged. error IpRoyaltyVault__IpTagged(); - error IpRoyaltyVault__ZeroDisputeModule(); + + /// @notice IP Royalty Vault is paused. error IpRoyaltyVault__EnforcedPause(); //////////////////////////////////////////////////////////////////////////// - // ModuleRegistry // + // Module Registry // //////////////////////////////////////////////////////////////////////////// + /// @notice Zero address provided for Access Manager in initializer. error ModuleRegistry__ZeroAccessManager(); + + /// @notice Module is zero address. error ModuleRegistry__ModuleAddressZeroAddress(); + + /// @notice Provided module address is not a contract. error ModuleRegistry__ModuleAddressNotContract(); + + /// @notice Module is already registered. error ModuleRegistry__ModuleAlreadyRegistered(); + + /// @notice Provided module name is empty string. error ModuleRegistry__NameEmptyString(); + + /// @notice Provided module name is already regsitered. error ModuleRegistry__NameAlreadyRegistered(); + + /// @notice Module name does not match the given name. error ModuleRegistry__NameDoesNotMatch(); + + /// @notice Module is not registered error ModuleRegistry__ModuleNotRegistered(); + + /// @notice Provided interface ID is zero bytes4. error ModuleRegistry__InterfaceIdZero(); + + /// @notice Module type is already registered. error ModuleRegistry__ModuleTypeAlreadyRegistered(); + + /// @notice Module type is not registered. error ModuleRegistry__ModuleTypeNotRegistered(); + + /// @notice Module address does not support the interface ID (module type). error ModuleRegistry__ModuleNotSupportExpectedModuleTypeInterfaceId(); + + /// @notice Module type is empty string. error ModuleRegistry__ModuleTypeEmptyString(); //////////////////////////////////////////////////////////////////////////// - // AccessController // + // Access Controller // //////////////////////////////////////////////////////////////////////////// + /// @notice Zero address provided for Access Manager in initializer. error AccessController__ZeroAccessManager(); + + /// @notice IP Account is zero address. error AccessController__IPAccountIsZeroAddress(); + + /// @notice IP Account is not a valid SP IP Account address. error AccessController__IPAccountIsNotValid(address ipAccount); + + /// @notice Signer is zero address. error AccessController__SignerIsZeroAddress(); + + /// @notice Caller is not the IP Account or its owner. error AccessController__CallerIsNotIPAccountOrOwner(); + + /// @notice Invalid permission value, must be 0 (ABSTAIN), 1 (ALLOW) or 2 (DENY). error AccessController__PermissionIsNotValid(); + + /// @notice Both the caller and recipient (to) are not registered modules. error AccessController__BothCallerAndRecipientAreNotRegisteredModule(address signer, address to); + + /// @notice Permission denied. error AccessController__PermissionDenied(address ipAccount, address signer, address to, bytes4 func); //////////////////////////////////////////////////////////////////////////// - // AccessControlled // + // Access Controlled // //////////////////////////////////////////////////////////////////////////// + + /// @notice Zero address passed. error AccessControlled__ZeroAddress(); + + /// @notice IP Account is not a valid SP IP Account address. error AccessControlled__NotIpAccount(address ipAccount); + + /// @notice Caller is not the IP Account. error AccessControlled__CallerIsNotIpAccount(address caller); //////////////////////////////////////////////////////////////////////////// - // CoreMetadataModule // + // Core Metadata Module // //////////////////////////////////////////////////////////////////////////// + + /// @notice Core metadata is already frozen (immutable). error CoreMetadataModule__MetadataAlreadyFrozen(); //////////////////////////////////////////////////////////////////////////// - // ProtocolPauseAdmin // + // Protocol Pause Admin // //////////////////////////////////////////////////////////////////////////// + + /// @notice Zero address passed. error ProtocolPauseAdmin__ZeroAddress(); + + /// @notice Adding a contract that is paused. error ProtocolPauseAdmin__AddingPausedContract(); + + /// @notice Contract is already added to the pausable list. error ProtocolPauseAdmin__PausableAlreadyAdded(); + + /// @notice Removing a contract that is not in the pausable list. error ProtocolPauseAdmin__PausableNotFound(); } diff --git a/contracts/lib/PILicenseTemplateErrors.sol b/contracts/lib/PILicenseTemplateErrors.sol index e66c56f08..2e2a84288 100644 --- a/contracts/lib/PILicenseTemplateErrors.sol +++ b/contracts/lib/PILicenseTemplateErrors.sol @@ -4,27 +4,42 @@ pragma solidity 0.8.23; /// @title PILicenseTemplate Errors Library /// @notice Library for all PILicenseTemplate related contract errors. library PILicenseTemplateErrors { - //////////////////////////////////////////////////////////////////////////// - // PILicenseTemplate // - //////////////////////////////////////////////////////////////////////////// + /// @notice Zero address provided for Access Manager at initialization. + error PILicenseTemplate__ZeroAccessManager(); + /// @notice Cannot add commercializers when commercial use is disabled. error PILicenseTemplate__CommercialDisabled_CantAddCommercializers(); + + /// @notice Provided commercializer does not support IHookModule. error PILicenseTemplate__CommercializerCheckerDoesNotSupportHook(address checker); + + /// @notice PIL terms royalty policy is not whitelisted by the Royalty Module. error PILicenseTemplate__RoyaltyPolicyNotWhitelisted(); + + /// @notice PIL terms currency token is not whitelisted by the Royalty Module. error PILicenseTemplate__CurrencyTokenNotWhitelisted(); + + /// @notice Royalty policy requires a currency token. error PILicenseTemplate__RoyaltyPolicyRequiresCurrencyToken(); + + /// @notice Cannot add commercial attribution when commercial use is disabled. error PILicenseTemplate__CommercialDisabled_CantAddAttribution(); + + /// @notice Cannot add commercial revenue share when commercial use is disabled. error PILicenseTemplate__CommercialDisabled_CantAddRevShare(); + + /// @notice Cannot add commercial royalty policy when commercial use is disabled. + error PILicenseTemplate__CommercialDisabled_CantAddRoyaltyPolicy(); + + /// @notice Royalty policy is required when commercial use is enabled. + error PILicenseTemplate__CommercialEnabled_RoyaltyPolicyRequired(); + + /// @notice Cannot add derivative attribution when derivative use is disabled. error PILicenseTemplate__DerivativesDisabled_CantAddAttribution(); + + /// @notice Cannot add derivative approval when derivative use is disabled. error PILicenseTemplate__DerivativesDisabled_CantAddApproval(); + + /// @notice Cannot add derivative reciprocal when derivative use is disabled. error PILicenseTemplate__DerivativesDisabled_CantAddReciprocal(); - error PILicenseTemplate__LicenseTermsNotFound(); - error PILicenseTemplate__CommercialDisabled_CantAddRoyaltyPolicy(); - error PILicenseTemplate__CommercialEnabled_RoyaltyPolicyRequired(); - error PILicenseTemplate__ReciprocalButDifferentPolicyIds(); - error PILicenseTemplate__ReciprocalValueMismatch(); - error PILicenseTemplate__CommercialValueMismatch(); - error PILicenseTemplate__StringArrayMismatch(); - error PILicenseTemplate__CommercialDisabled_CantAddMintingFee(); - error PILicenseTemplate__CommercialDisabled_CantAddMintingFeeToken(); } diff --git a/contracts/lib/ShortStringOps.sol b/contracts/lib/ShortStringOps.sol new file mode 100644 index 000000000..d5d47e6e1 --- /dev/null +++ b/contracts/lib/ShortStringOps.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.23; + +import { ShortString, ShortStrings } from "@openzeppelin/contracts/utils/ShortStrings.sol"; +import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; + +/// @notice Library for working with Openzeppelin's ShortString data types. +library ShortStringOps { + using ShortStrings for *; + using Strings for *; + + /// @dev Convert string to bytes32 using ShortString + function stringToBytes32(string memory s) internal pure returns (bytes32) { + return ShortString.unwrap(s.toShortString()); + } +} diff --git a/contracts/modules/dispute/DisputeModule.sol b/contracts/modules/dispute/DisputeModule.sol index 06e6ad0a0..fd9e466bd 100644 --- a/contracts/modules/dispute/DisputeModule.sol +++ b/contracts/modules/dispute/DisputeModule.sol @@ -14,7 +14,7 @@ import { ILicenseRegistry } from "../../interfaces/registries/ILicenseRegistry.s import { IDisputeModule } from "../../interfaces/modules/dispute/IDisputeModule.sol"; import { IArbitrationPolicy } from "../../interfaces/modules/dispute/policies/IArbitrationPolicy.sol"; import { Errors } from "../../lib/Errors.sol"; -import { ShortStringOps } from "../../utils/ShortStringOps.sol"; +import { ShortStringOps } from "../../lib/ShortStringOps.sol"; import { ProtocolPausableUpgradeable } from "../../pause/ProtocolPausableUpgradeable.sol"; /// @title Dispute Module @@ -71,20 +71,20 @@ contract DisputeModule is ILicenseRegistry public immutable LICENSE_REGISTRY; /// Constructor - /// @param controller The address of the access controller - /// @param assetRegistry The address of the asset registry + /// @param accessController The address of the access controller + /// @param ipAssetRegistry The address of the asset registry /// @param licenseRegistry The address of the license registry /// @custom:oz-upgrades-unsafe-allow constructor constructor( - address controller, - address assetRegistry, + address accessController, + address ipAssetRegistry, address licenseRegistry - ) AccessControlled(controller, assetRegistry) { + ) AccessControlled(accessController, ipAssetRegistry) { if (licenseRegistry == address(0)) revert Errors.DisputeModule__ZeroLicenseRegistry(); - if (assetRegistry == address(0)) revert Errors.DisputeModule__ZeroAssetRegistry(); - if (controller == address(0)) revert Errors.DisputeModule__ZeroController(); + if (ipAssetRegistry == address(0)) revert Errors.DisputeModule__ZeroIPAssetRegistry(); + if (accessController == address(0)) revert Errors.DisputeModule__ZeroAccessController(); - IP_ASSET_REGISTRY = IIPAssetRegistry(assetRegistry); + IP_ASSET_REGISTRY = IIPAssetRegistry(ipAssetRegistry); LICENSE_REGISTRY = ILicenseRegistry(licenseRegistry); _disableInitializers(); } diff --git a/contracts/modules/licensing/PILicenseTemplate.sol b/contracts/modules/licensing/PILicenseTemplate.sol index 195f5b067..8c1adc221 100644 --- a/contracts/modules/licensing/PILicenseTemplate.sol +++ b/contracts/modules/licensing/PILicenseTemplate.sol @@ -12,7 +12,6 @@ import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/ import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; // contracts -import { Errors } from "../../lib/Errors.sol"; import { IHookModule } from "../../interfaces/modules/base/IHookModule.sol"; import { ILicenseRegistry } from "../../interfaces/registries/ILicenseRegistry.sol"; import { IRoyaltyModule } from "../../interfaces/modules/royalty/IRoyaltyModule.sol"; @@ -68,7 +67,7 @@ contract PILicenseTemplate is /// @param metadataURI The URL to the off chain metadata function initialize(address accessManager, string memory name, string memory metadataURI) external initializer { if (accessManager == address(0)) { - revert Errors.PILicenseTemplate__ZeroAccessManager(); + revert PILicenseTemplateErrors.PILicenseTemplate__ZeroAccessManager(); } __BaseLicenseTemplate_init(name, metadataURI); __AccessManaged_init(accessManager); diff --git a/contracts/registries/IPAccountRegistry.sol b/contracts/registries/IPAccountRegistry.sol index 9d64c5ec1..6a8324187 100644 --- a/contracts/registries/IPAccountRegistry.sol +++ b/contracts/registries/IPAccountRegistry.sol @@ -24,7 +24,7 @@ abstract contract IPAccountRegistry is IIPAccountRegistry { /// @custom:oz-upgrades-unsafe-allow constructor constructor(address erc6551Registry, address ipAccountImpl) { - if (ipAccountImpl == address(0)) revert Errors.IPAccountRegistry_InvalidIpAccountImpl(); + if (ipAccountImpl == address(0)) revert Errors.IPAccountRegistry_ZeroIpAccountImpl(); IP_ACCOUNT_IMPL = ipAccountImpl; IP_ACCOUNT_SALT = bytes32(0); ERC6551_PUBLIC_REGISTRY = erc6551Registry; diff --git a/contracts/utils/ShortStringOps.sol b/contracts/utils/ShortStringOps.sol deleted file mode 100644 index c9914132f..000000000 --- a/contracts/utils/ShortStringOps.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity 0.8.23; - -import { ShortString, ShortStrings } from "@openzeppelin/contracts/utils/ShortStrings.sol"; -import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; - -/// @notice Library for working with Openzeppelin's ShortString data types. -library ShortStringOps { - using ShortStrings for *; - using Strings for *; - - /// @dev Compares whether two ShortStrings are equal. - function equal(ShortString a, ShortString b) internal pure returns (bool) { - return ShortString.unwrap(a) == ShortString.unwrap(b); - } - - /// @dev Checks whether a ShortString and a regular string are equal. - function equal(ShortString a, string memory b) internal pure returns (bool) { - return equal(a, b.toShortString()); - } - - /// @dev Checks whether a regular string and a ShortString are equal. - function equal(string memory a, ShortString b) internal pure returns (bool) { - return equal(a.toShortString(), b); - } - - /// @dev Checks whether a bytes32 object and ShortString are equal. - function equal(bytes32 a, ShortString b) internal pure returns (bool) { - return a == ShortString.unwrap(b); - } - - /// @dev Checks whether a string and bytes32 object are equal. - function equal(string memory a, bytes32 b) internal pure returns (bool) { - return equal(a, ShortString.wrap(b)); - } - - /// @dev Checks whether a bytes32 object and string are equal. - function equal(bytes32 a, string memory b) internal pure returns (bool) { - return equal(ShortString.wrap(a), b); - } - - function stringToBytes32(string memory s) internal pure returns (bytes32) { - return ShortString.unwrap(s.toShortString()); - } - - function bytes32ToString(bytes32 b) internal pure returns (string memory) { - return ShortString.wrap(b).toString(); - } - - function toShortString(uint256 value) internal pure returns (ShortString) { - return value.toString().toShortString(); - } -} diff --git a/test/foundry/modules/dispute/DisputeModule.t.sol b/test/foundry/modules/dispute/DisputeModule.t.sol index 24c1702f2..76b747601 100644 --- a/test/foundry/modules/dispute/DisputeModule.t.sol +++ b/test/foundry/modules/dispute/DisputeModule.t.sol @@ -10,7 +10,7 @@ import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/P import { Errors } from "contracts/lib/Errors.sol"; import { IModule } from "contracts/interfaces/modules/base/IModule.sol"; import { ArbitrationPolicySP } from "contracts/modules/dispute/policies/ArbitrationPolicySP.sol"; -import { ShortStringOps } from "contracts/utils/ShortStringOps.sol"; +import { ShortStringOps } from "contracts/lib/ShortStringOps.sol"; import { IDisputeModule } from "contracts/interfaces/modules/dispute/IDisputeModule.sol"; // test import { BaseTest } from "test/foundry/utils/BaseTest.t.sol";