generated from storyprotocol/solidity-template
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactors to support global IP asset identification (#129)
* Refactors to support global IP asset identification * Removes console logs * Finalizes initial refactor * Fixes import ordering
- Loading branch information
Showing
65 changed files
with
1,707 additions
and
1,639 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity ^0.8.13; | ||
|
||
import { Clones } from '@openzeppelin/contracts/proxy/Clones.sol'; | ||
import { IPAsset } from "contracts/lib/IPAsset.sol"; | ||
import { AccessControl } from "contracts/lib/AccessControl.sol"; | ||
import { Errors } from "contracts/lib/Errors.sol"; | ||
import { AccessControlledUpgradeable } from "./access-control/AccessControlledUpgradeable.sol"; | ||
import { LicenseRegistry } from "contracts/modules/licensing/LicenseRegistry.sol"; | ||
import { IIPAssetOrgFactory } from "contracts/interfaces/IIPAssetOrgFactory.sol"; | ||
import { IPAssetOrg } from "contracts/ip-assets/IPAssetOrg.sol"; | ||
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; | ||
|
||
/// @notice IP Asset Organization Factory Contract | ||
/// TODO(ramarti): Extend the base hooks contract utilized by SP modules. | ||
contract IPAssetOrgFactory is | ||
UUPSUpgradeable, | ||
AccessControlledUpgradeable, | ||
IIPAssetOrgFactory | ||
{ | ||
|
||
/// @notice Base template implementation contract used for new IP Asset Org creation. | ||
address public immutable IP_ASSET_ORG_IMPL = address(new IPAssetOrg()); | ||
|
||
string private constant _VERSION = "0.1.0"; | ||
|
||
// TODO(@leeren): Fix storage hash | ||
// keccak256(bytes.concat(bytes32(uint256(keccak256("story-protocol.ip-asset-org-factory.storage")) - 1))) | ||
bytes32 private constant _STORAGE_LOCATION = 0x1b0b8fa444ff575656111a4368b8e6a743b70cbf31ffb9ee2c7afe1983f0e378; | ||
|
||
/// @custom:storage-location erc7201:story-protocol.ip-asset-org-factory.storage | ||
// TODO: Extend IP asset org storage to support other relevant configurations | ||
struct IPAssetOrgFactoryStorage { | ||
/// @dev Tracks mappings from ipAssetOrg to whether they were registered. | ||
mapping(address => bool) registered; | ||
} | ||
|
||
/// @notice Checks if an address is a valid IP Asset Organization. | ||
/// @param ipAssetOrg_ the address to check | ||
/// @return true if `ipAssetOrg_` is a valid IP Asset Organization, false otherwise | ||
function isIpAssetOrg( | ||
address ipAssetOrg_ | ||
) external view returns (bool) { | ||
IPAssetOrgFactoryStorage storage $ = _getIpAssetOrgFactoryStorage(); | ||
return $.registered[ipAssetOrg_]; | ||
} | ||
|
||
/// @notice Returns the current version of the factory contract. | ||
function version() external pure override returns (string memory) { | ||
return _VERSION; | ||
} | ||
|
||
|
||
/// @notice Registers a new ipAssetOrg for IP asset collection management. | ||
/// @param params_ Parameters required for ipAssetOrg creation. | ||
/// TODO: Converge on core primitives utilized for ipAssetOrg management. | ||
/// TODO: Add ipAssetOrg-wide module configurations to the registration process. | ||
// TODO: Remove registry | ||
function registerIPAssetOrg( | ||
IPAsset.RegisterIPAssetOrgParams calldata params_ | ||
) public returns (address) { | ||
address ipAssetOrg = Clones.clone(IP_ASSET_ORG_IMPL); | ||
IPAssetOrg(ipAssetOrg).initialize(IPAsset.InitIPAssetOrgParams({ | ||
registry: params_.registry, | ||
owner: msg.sender, | ||
name: params_.name, | ||
symbol: params_.symbol, | ||
description: params_.description, | ||
licensingModule: params_.licensingModule, | ||
collectModule: params_.collectModule | ||
})); | ||
|
||
/// TODO(ramarti): Switch to global licensing registry. | ||
LicenseRegistry licenseRegistry = new LicenseRegistry( | ||
ipAssetOrg, | ||
string.concat("Licenses for ", params_.name), | ||
string.concat("sl", params_.symbol) | ||
); | ||
IPAssetOrg(ipAssetOrg).setLicenseRegistry(address(licenseRegistry)); | ||
|
||
// Set the registration status of the IP Asset Org to be true. | ||
IPAssetOrgFactoryStorage storage $ = _getIpAssetOrgFactoryStorage(); | ||
$.registered[ipAssetOrg] = true; | ||
|
||
emit IPAssetOrgRegistered( | ||
msg.sender, | ||
ipAssetOrg, | ||
params_.name, | ||
params_.symbol, | ||
params_.tokenURI | ||
); | ||
return ipAssetOrg; | ||
|
||
} | ||
|
||
/// @notice Initializes the IPAssetOrgFactory contract. | ||
/// @param accessControl_ Address of the contract responsible for access control. | ||
function initialize(address accessControl_) public initializer { | ||
__UUPSUpgradeable_init(); | ||
__AccessControlledUpgradeable_init(accessControl_); | ||
} | ||
|
||
function _authorizeUpgrade( | ||
address newImplementation_ | ||
) internal virtual override onlyRole(AccessControl.UPGRADER_ROLE) {} | ||
|
||
function _getIpAssetOrgFactoryStorage() | ||
private | ||
pure | ||
returns (IPAssetOrgFactoryStorage storage $) | ||
{ | ||
assembly { | ||
$.slot := _STORAGE_LOCATION | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity ^0.8.19; | ||
|
||
import { IIPAssetRegistry } from "contracts/interfaces/IIPAssetRegistry.sol"; | ||
|
||
/// @title IP Asset Registry | ||
/// @notice The source of truth for IP on Story Protocol. | ||
// TO-DO(@leeren): Add authorization around IP Asset registration and ownership transferring. | ||
// TO-DO(ramarti): Add authorization around IP Asset Org transfer of IP Assets. | ||
contract IPAssetRegistry is IIPAssetRegistry { | ||
|
||
/// @notice Core attributes that make up an IP Asset. | ||
// TO-DO: Add other core IP Asset primitives (namely module linking). | ||
struct IPAsset { | ||
address owner; // TO-DO: Consider removing this in the future. | ||
address ipAssetOrg; | ||
} | ||
|
||
/// @notice Mapping from IP asset ids to registry records. | ||
mapping(uint256 => IPAsset) ipAssets; | ||
|
||
/// @notice Tracks the total number of IP Assets in existence. | ||
uint256 numIPAssets = 0; | ||
|
||
/// @notice Registers a new IP Asset. | ||
/// @param owner_ The address of the IP Asset. | ||
/// @param ipAssetOrg_ The address of the IP Asset Org. | ||
// TO-DO(@leeren): Add registration authorization (likely based around IPAssetOrg enrollment). | ||
// TO_DO(ramarti): Add module registration via resolver / registry. | ||
function register(address owner_, address ipAssetOrg_) public returns (uint256) { | ||
uint256 ipAssetId = numIPAssets++; | ||
ipAssets[ipAssetId] = IPAsset({ | ||
owner: owner_, | ||
ipAssetOrg: ipAssetOrg_ | ||
}); | ||
|
||
emit IPAssetRegistered(ipAssetId, owner_, ipAssetOrg_); | ||
return ipAssetId; | ||
} | ||
|
||
function setOwner(uint256 ipAssetId_, address owner_) public { | ||
ipAssets[ipAssetId_].owner = owner_; | ||
emit OwnerTransferred(ipAssetId_, owner_); | ||
} | ||
|
||
function setIpAssetOrg(uint256 ipAssetId_, address ipAssetOrg_) public { | ||
ipAssets[ipAssetId_].ipAssetOrg = ipAssetOrg_; | ||
emit OrgTransferred(ipAssetId_, ipAssetOrg_); | ||
} | ||
|
||
/// @notice Gets the IP Asset Org that administers a specific IP Asset. | ||
/// @param ipAssetId_ The id of the IP Asset being queried. | ||
function ipAssetOrg(uint256 ipAssetId_) public returns (address) { | ||
return ipAssets[ipAssetId_].ipAssetOrg; | ||
} | ||
|
||
/// @notice Gets the owner of a specific IP Asset. | ||
/// @param ipAssetId_ The id of the IP Asset being queried. | ||
function ipAssetOwner(uint256 ipAssetId_) public returns (address) { | ||
return ipAssets[ipAssetId_].owner; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity ^0.8.19; | ||
|
||
import { IVersioned } from "./utils/IVersioned.sol"; | ||
import { IPAsset } from "contracts/lib/IPAsset.sol"; | ||
|
||
interface IIPAssetOrgFactory is IVersioned { | ||
|
||
event IPAssetOrgRegistered( | ||
address owner_, | ||
address ipAssetOrg_, | ||
string name_, | ||
string symbol_, | ||
string tokenURI_ | ||
); | ||
|
||
function registerIPAssetOrg(IPAsset.RegisterIPAssetOrgParams calldata params_) external returns(address); | ||
|
||
function isIpAssetOrg(address ipAssetOrg_) external view returns (bool); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { IPAsset } from "contracts/lib/IPAsset.sol"; | ||
|
||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity ^0.8.19; | ||
|
||
interface IIPAssetRegistry { | ||
|
||
event IPAssetRegistered( | ||
uint256 ipAssetId_, | ||
address owner_, | ||
address ipAssetOrg_ | ||
); | ||
|
||
event OrgTransferred( | ||
uint256 indexed ipAssetId_, | ||
address indexed owner_ | ||
); | ||
|
||
event OwnerTransferred( | ||
uint256 indexed ipAssetId_, | ||
address indexed owner_ | ||
); | ||
|
||
} |
Oops, something went wrong.