diff --git a/contracts/IPAssetRegistry.sol b/contracts/IPAssetRegistry.sol index c56eca2b..12a57237 100644 --- a/contracts/IPAssetRegistry.sol +++ b/contracts/IPAssetRegistry.sol @@ -9,7 +9,12 @@ import { ModuleRegistryKeys } from "contracts/lib/modules/ModuleRegistryKeys.sol import { Errors } from "contracts/lib/Errors.sol"; /// @title Global IP Asset Registry -/// @notice The source of truth for IP on Story Protocol. +/// @notice The global IP Asset Registry (GIPR) acts as the source of truth for IP +/// attribution in Story Protocol. All IP must be registered through a +/// protocol-approved registration module, which as part of the process will +/// create a record in the GIPR. Note that the GIPR only defines the core +/// attributes related to an IP asset - all other attributes, which will be +/// specific for a given module, will be queried through the module registry. contract IPAssetRegistry is IIPAssetRegistry { /// @notice Core attributes that make up an IP Asset. diff --git a/contracts/StoryProtocol.sol b/contracts/StoryProtocol.sol index 119b297b..1e2ef3d1 100644 --- a/contracts/StoryProtocol.sol +++ b/contracts/StoryProtocol.sol @@ -14,6 +14,13 @@ import { Licensing } from "contracts/lib/modules/Licensing.sol"; import { FixedSet } from "contracts/utils/FixedSet.sol"; import { Multicall } from "@openzeppelin/contracts/utils/Multicall.sol"; +/// @title Story Protocol Gateway Contract +/// @notice The Story Protocol contract acts as a global gateway for calling all +/// protocol-standardized IP actions (based on their enrolled modules). +/// Most functions can be solely executed through this contract, as it will +/// be actively maintained and upgraded to support all standardized modules. +/// In the future, for more customized logic, IP Orgs may choose to create +/// their own frontend contracts (gateways) for IP interaction. contract StoryProtocol is Multicall { IIPOrgController public immutable IP_ORG_CONTROLLER; diff --git a/contracts/access-control/AccessControlSingleton.sol b/contracts/access-control/AccessControlSingleton.sol index 21a14743..58063902 100644 --- a/contracts/access-control/AccessControlSingleton.sol +++ b/contracts/access-control/AccessControlSingleton.sol @@ -9,12 +9,13 @@ import { Multicall } from "@openzeppelin/contracts/utils/Multicall.sol"; import { AccessControlUpgradeable } from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -/// @notice AccessControlSingleton contract. Manages protocol admin keys. Other contracts might inherit -/// AccessControlled or its upgradeable version to use the onlyRole modifier. -/// TODO: Evaluate making this contract AccessControlEnumerableUpgradeable so it could enforce unique roles -/// (as in only 1 address can have a role at a time) +/// @title Access Control Singleton +/// @notice This contract serves as the global source of truth for role-based authorization. +/// Contracts that inherit the AccessControlled contract or its upgradable variant +/// are may be granted granular access to certain roles by utilizing the `onlyRole` +/// modifier with the required role input as a parameter. contract AccessControlSingleton is - AccessControlUpgradeable, +AccessControlUpgradeable, UUPSUpgradeable, Multicall, IVersioned diff --git a/contracts/access-control/AccessControlled.sol b/contracts/access-control/AccessControlled.sol index d30a2748..76ea6561 100644 --- a/contracts/access-control/AccessControlled.sol +++ b/contracts/access-control/AccessControlled.sol @@ -9,6 +9,9 @@ import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.so // solhint-disable-next-line max-line-length import { ERC165CheckerUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165CheckerUpgradeable.sol"; +/// @title Access Controlled Contract +/// @notice This contract is to be inherited by any protocol components that require granular +/// roles for execution, as defined by the Access Control Singleton contract. abstract contract AccessControlled is IAccessControlled { using ERC165CheckerUpgradeable for address; @@ -23,6 +26,8 @@ abstract contract AccessControlled is IAccessControlled { _; } + /// @notice Instantiates a new Access Controlled contract. + /// @param accessControl_ The global Access Control Singleton contract address. constructor(address accessControl_) { if (!accessControl_.supportsInterface(type(IAccessControl).interfaceId)) revert Errors.UnsupportedInterface("IAccessControl"); diff --git a/contracts/access-control/AccessControlledUpgradeable.sol b/contracts/access-control/AccessControlledUpgradeable.sol index 5be70d73..b8bab378 100644 --- a/contracts/access-control/AccessControlledUpgradeable.sol +++ b/contracts/access-control/AccessControlledUpgradeable.sol @@ -9,6 +9,9 @@ import { AccessControl } from "contracts/lib/AccessControl.sol"; import { IAccessControlled } from "contracts/interfaces/access-control/IAccessControlled.sol"; import { Errors } from "contracts/lib/Errors.sol"; +/// @title Access Controlled Contract (upgradeable variant) +/// @notice This contract is to be inherited by any upgradeable protocol components that require +/// granular roles for execution, as defined by the Access Control Singleton contract. abstract contract AccessControlledUpgradeable is UUPSUpgradeable, IAccessControlled { using ERC165CheckerUpgradeable for address; @@ -42,6 +45,7 @@ abstract contract AccessControlledUpgradeable is UUPSUpgradeable, IAccessControl emit AccessControlUpdated(accessControl_); } + /// @notice Gets the global Access Control Singleton configured for the protocol. function getAccessControl() public view returns (address) { AccessControlledStorage storage $ = _getAccessControlledUpgradeable(); return address($.accessControl); @@ -71,6 +75,7 @@ abstract contract AccessControlledUpgradeable is UUPSUpgradeable, IAccessControl return $.accessControl.hasRole(role_, account_); } + /// @dev Helper function to get the EIP-7201 storage slot for the contract. function _getAccessControlledUpgradeable() private pure diff --git a/contracts/interfaces/access-control/IAccessControlled.sol b/contracts/interfaces/access-control/IAccessControlled.sol index 6a99e99b..58a87d7c 100644 --- a/contracts/interfaces/access-control/IAccessControlled.sol +++ b/contracts/interfaces/access-control/IAccessControlled.sol @@ -4,6 +4,8 @@ pragma solidity ^0.8.19; /// @title Access Controlled Interface interface IAccessControlled { + /// @notice Emits when the global Access Control singleton contract is updated. + /// @param accessControl Address of the protocol-wide Access Control singleton contract. event AccessControlUpdated(address indexed accessControl); } diff --git a/contracts/interfaces/ip-org/IIPOrgFactory.sol b/contracts/interfaces/ip-org/IIPOrgFactory.sol deleted file mode 100644 index 6d2e095c..00000000 --- a/contracts/interfaces/ip-org/IIPOrgFactory.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import { IVersioned } from "../utils/IVersioned.sol"; -import { IPOrgParams } from "contracts/lib/IPOrgParams.sol"; - -interface IIPOrgController is IVersioned { - - event IPOrgRegistered( - address owner, - address ipAssetOrg, - string name, - string symbol, - string tokenURI, - string[] ipAssetTypes - ); - - function registerIpOrg(IPOrgParams.RegisterIPOrgParams calldata params_) external returns(address); - - function isIpOrg(address ipAssetOrg_) external view returns (bool); -} diff --git a/contracts/ip-org/IPOrg.sol b/contracts/ip-org/IPOrg.sol index e67d7a67..7a04509d 100644 --- a/contracts/ip-org/IPOrg.sol +++ b/contracts/ip-org/IPOrg.sol @@ -13,8 +13,12 @@ import { IPAssetRegistry } from "contracts/IPAssetRegistry.sol"; import { ModuleRegistryKeys } from "contracts/lib/modules/ModuleRegistryKeys.sol"; import { Errors } from "contracts/lib/Errors.sol"; -/// @notice IP Asset Organization -/// TODO(leeren): Deprecate upgradeability once the IPOrg contracts is finalized. +/// @title IP Organization Contract +/// @notice An IP Org represents a collection of IP Assets governed under a single +/// administrative entity. It serves both as an org-branded NFT wrapper of +/// the IP Asset group and as a conduit used by the IP registration module +/// for transferring IP ownership and configuring its IP-related metadata. +/// Crations of new IP Orgs happen through the IP Org Controller contract. contract IPOrg is IIPOrg, ERC721Upgradeable @@ -129,8 +133,8 @@ contract IPOrg is _transfer(from_, to_, id_); } - /// Returns the IP Org asset type for a given IP Org asset. - /// @dev reverts if id does not exist. + /// @notice Returns the IP Org asset type for a given IP Org asset. + /// @param id_ The identifier of the IP asset within the IP Org. function ipOrgAssetType(uint256 id_) public view returns (uint8) { if (!_exists(id_)) { revert Errors.IPOrg_IdDoesNotExist(); diff --git a/contracts/ip-org/IPOrgController.sol b/contracts/ip-org/IPOrgController.sol index 6fccb1fd..c3e4b584 100644 --- a/contracts/ip-org/IPOrgController.sol +++ b/contracts/ip-org/IPOrgController.sol @@ -17,8 +17,9 @@ import { IPOrg } from "contracts/ip-org/IPOrg.sol"; import { AccessControl } from "contracts/lib/AccessControl.sol"; /// @title IP Org Controller Contract -/// @custom:version 0.1.0 -/// TODO(leeren): Deprecate upgradeability once IPOrg contracts are finalized. +/// @notice The IP Org Controller is the protocol-wide factory contract for creating +/// and tracking IP Orgs. On top of this, it acts as the ownership controller +/// for IP Orgs, allowing orgs to transfer ownership through a 2-step process. contract IPOrgController is UUPSUpgradeable, AccessControlledUpgradeable, @@ -26,8 +27,6 @@ contract IPOrgController is { /// @notice Tracks ownership and registration of IPOrgs. - /// TODO(leeren): Add tracking for allowlisted callers of each ipOrg. - /// TODO(leeren): Add deterministic identifiers for ipOrgs using CREATE2. struct IPOrgRecord { bool registered; address owner; diff --git a/contracts/modules/registration/RegistrationModule.sol b/contracts/modules/registration/RegistrationModule.sol index cc47875a..c170efe4 100644 --- a/contracts/modules/registration/RegistrationModule.sol +++ b/contracts/modules/registration/RegistrationModule.sol @@ -17,7 +17,10 @@ import { IPAsset } from "contracts/lib/IPAsset.sol"; /// @title Registration Module -/// @notice Handles registration and transferring of IP assets.. +/// @notice The registration module is responsible for registration, transferring, and +/// metadata management of IP assets. During registration, this module will +/// create register the IP asset in the global IP asset registry, and then +/// wrap it as an NFT under its governing IP Org. contract RegistrationModule is BaseModule, IRegistrationModule, AccessControlled { using Strings for uint256;