IIPAsset
Title: IIPAsset
Interface for IP Asset NFT contract representing intellectual property ownership
ERC-721 upgradeable contract with metadata versioning and license management
Functions
initialize
Initializes the IPAsset contract (proxy pattern)
Sets up ERC721, AccessControl, Pausable, and UUPS upgradeable patterns
function initialize(
string memory name,
string memory symbol,
address admin,
address licenseToken,
address arbitrator
) external;
Parameters
| Name | Type | Description |
|---|---|---|
name | string | The name for the ERC721 token |
symbol | string | The symbol for the ERC721 token |
admin | address | Address to receive all initial admin roles (DEFAULT_ADMIN, PAUSER, UPGRADER) |
licenseToken | address | Address of the LicenseToken contract |
arbitrator | address | Address of the GovernanceArbitrator contract |
mintIP
Mints a new IP asset NFT
Creates a token with auto-incrementing ID and stores initial metadata
function mintIP(address to, string memory metadataURI) external returns (uint256 tokenId);
Parameters
| Name | Type | Description |
|---|---|---|
to | address | Address to receive the newly minted IP asset |
metadataURI | string | IPFS or HTTP URI pointing to IP metadata |
Returns
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The ID of the newly minted token |
mintLicense
Creates a new license for an IP asset
Delegates to LicenseToken contract to mint the license. Only the IP asset owner can mint licenses. Emits LicenseRegistered event for off-chain tracking.
function mintLicense(
uint256 ipTokenId,
address licensee,
uint256 supply,
string memory publicMetadataURI,
string memory privateMetadataURI,
uint256 expiryTime,
string memory terms,
bool isExclusive,
uint256 paymentInterval
) external returns (uint256 licenseId);
Parameters
| Name | Type | Description |
|---|---|---|
ipTokenId | uint256 | The IP asset to create a license for |
licensee | address | Address to receive the license |
supply | uint256 | Number of license tokens to mint (ERC-1155 supply) |
publicMetadataURI | string | Publicly visible license metadata URI |
privateMetadataURI | string | Private license terms URI (access controlled) |
expiryTime | uint256 | Unix timestamp when license expires |
terms | string | Human-readable license terms |
isExclusive | bool | Whether this is an exclusive license |
paymentInterval | uint256 | Payment interval in seconds (0 = one-time, >0 = recurring) |
Returns
| Name | Type | Description |
|---|---|---|
licenseId | uint256 | The ID of the newly created license |
updateMetadata
Updates the metadata URI for an IP asset
Only the token owner can update. Creates a new version in history.
function updateMetadata(uint256 tokenId, string memory newURI) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IP asset token ID |
newURI | string | The new metadata URI |
configureRevenueSplit
Configures revenue split for an IP asset
Only the token owner can configure. Delegates to RevenueDistributor.
function configureRevenueSplit(uint256 tokenId, address[] memory recipients, uint256[] memory shares) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IP asset token ID |
recipients | address[] | Array of addresses to receive revenue shares |
shares | uint256[] | Array of share amounts in basis points (must sum to 10000) |
setRoyaltyRate
Sets the royalty rate for an IP asset
Only the token owner can set. Delegates to RevenueDistributor.
function setRoyaltyRate(uint256 tokenId, uint256 basisPoints) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IP asset token ID |
basisPoints | uint256 | Royalty rate in basis points (e.g., 1000 = 10%) |
burn
Burns an IP asset NFT
Only owner can burn. Blocked if active licenses exist or dispute is active.
function burn(uint256 tokenId) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IP asset token ID to burn |
setDisputeStatus
Sets the dispute status for an IP asset
Only callable by ARBITRATOR_ROLE (GovernanceArbitrator contract)
function setDisputeStatus(uint256 tokenId, bool hasDispute) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IP asset token ID |
hasDispute | bool | Whether there is an active dispute |
setLicenseTokenContract
Updates the LicenseToken contract address
Only callable by admin
function setLicenseTokenContract(address licenseToken) external;
Parameters
| Name | Type | Description |
|---|---|---|
licenseToken | address | New LicenseToken contract address |
setArbitratorContract
Updates the GovernanceArbitrator contract address
Only callable by admin
function setArbitratorContract(address arbitrator) external;
Parameters
| Name | Type | Description |
|---|---|---|
arbitrator | address | New GovernanceArbitrator contract address |
setRevenueDistributorContract
Updates the RevenueDistributor contract address
Only callable by admin
function setRevenueDistributorContract(address distributor) external;
Parameters
| Name | Type | Description |
|---|---|---|
distributor | address | New RevenueDistributor contract address |
updateActiveLicenseCount
Updates the active license count for an IP asset
Only callable by LICENSE_MANAGER_ROLE (LicenseToken contract)
function updateActiveLicenseCount(uint256 tokenId, int256 delta) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IP asset token ID |
delta | int256 | Change in license count (positive or negative) |
hasActiveDispute
Checks if an IP asset has an active dispute
function hasActiveDispute(uint256 tokenId) external view returns (bool hasDispute);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IP asset token ID |
Returns
| Name | Type | Description |
|---|---|---|
hasDispute | bool | Whether there is an active dispute |
pause
Pauses all state-changing operations
Only callable by DEFAULT_ADMIN_ROLE
function pause() external;
unpause
Unpauses all state-changing operations
Only callable by DEFAULT_ADMIN_ROLE
function unpause() external;
setPrivateMetadata
Sets private metadata for an IP asset
Only the IP asset owner can set private metadata
function setPrivateMetadata(uint256 tokenId, string memory metadata) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The ID of the IP asset |
metadata | string | The private metadata URI (IPFS, HTTP, etc.) |
getPrivateMetadata
Gets private metadata for an IP asset
Only the IP asset owner can read private metadata
function getPrivateMetadata(uint256 tokenId) external view returns (string memory);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The ID of the IP asset |
Returns
| Name | Type | Description |
|---|---|---|
<none> | string | metadata The private metadata URI |
wrapNFT
Wraps an external NFT into an IPAsset
Transfers the NFT to this contract and mints a new IPAsset token representing it. Only the NFT owner can wrap it. One NFT can only be wrapped once. Use setPrivateMetadata() after wrapping to add private metadata if needed.
function wrapNFT(address nftContract, uint256 nftTokenId, string memory metadataURI)
external
returns (uint256 ipTokenId);
Parameters
| Name | Type | Description |
|---|---|---|
nftContract | address | The address of the ERC721 contract |
nftTokenId | uint256 | The token ID of the NFT to wrap |
metadataURI | string | The metadata URI for the new IPAsset |
Returns
| Name | Type | Description |
|---|---|---|
ipTokenId | uint256 | The ID of the newly minted IPAsset token |
unwrapNFT
Unwraps an IPAsset to retrieve the original NFT
Burns the IPAsset token and returns the original NFT to the caller. Only the IPAsset owner can unwrap. Cannot unwrap if active licenses or disputes exist.
function unwrapNFT(uint256 tokenId) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IPAsset token ID to unwrap |
isWrapped
Checks if an IPAsset is wrapping an external NFT
function isWrapped(uint256 tokenId) external view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IPAsset token ID |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | True if the IPAsset wraps an NFT, false if it's a native IPAsset |
getWrappedNFT
Gets the wrapped NFT details for an IPAsset
function getWrappedNFT(uint256 tokenId) external view returns (address nftContract, uint256 nftTokenId);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IPAsset token ID |
Returns
| Name | Type | Description |
|---|---|---|
nftContract | address | The wrapped NFT contract address (zero address if not wrapped) |
nftTokenId | uint256 | The wrapped NFT token ID (zero if not wrapped) |
Events
IPMinted
Emitted when a new IP asset is minted
event IPMinted(uint256 indexed tokenId, address indexed owner, string metadataURI);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The ID of the newly minted token |
owner | address | The address that owns the new IP asset |
metadataURI | string | The URI pointing to the IP metadata |
MetadataUpdated
Emitted when IP metadata is updated
Includes old and new URIs for complete off-chain indexing without state tracking
event MetadataUpdated(uint256 indexed tokenId, string oldURI, string newURI, uint256 timestamp);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The ID of the token being updated |
oldURI | string | The previous metadata URI |
newURI | string | The new metadata URI |
timestamp | uint256 | The block timestamp when update occurred |
LicenseMinted
Emitted when a license is minted for an IP asset
event LicenseMinted(uint256 indexed ipTokenId, uint256 indexed licenseId);
Parameters
| Name | Type | Description |
|---|---|---|
ipTokenId | uint256 | The IP asset token ID |
licenseId | uint256 | The newly created license ID |
LicenseRegistered
Emitted when a license is registered for an IP asset
This event provides complete license context for off-chain indexing without requiring array storage. Indexers can build complete license lists by filtering this event by ipTokenId. This replaces the need for on-chain ipToLicenses[] array storage (gas optimization).
event LicenseRegistered(
uint256 indexed ipTokenId, uint256 indexed licenseId, address indexed licensee, uint256 supply, bool isExclusive
);
Parameters
| Name | Type | Description |
|---|---|---|
ipTokenId | uint256 | The IP asset token ID this license is for |
licenseId | uint256 | The ID of the newly registered license |
licensee | address | The address receiving the license |
supply | uint256 | Number of license tokens minted (ERC-1155 supply) |
isExclusive | bool | Whether this is an exclusive license |
RevenueSplitConfigured
Emitted when revenue split is configured for an IP asset
event RevenueSplitConfigured(uint256 indexed tokenId, address[] recipients, uint256[] shares);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IP asset token ID |
recipients | address[] | Array of recipient addresses |
shares | uint256[] | Array of share percentages (must sum to 10000 basis points) |
RoyaltyRateSet
Emitted when royalty rate is set for an IP asset
event RoyaltyRateSet(uint256 indexed tokenId, uint256 basisPoints);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IP asset token ID |
basisPoints | uint256 | Royalty rate in basis points (e.g., 1000 = 10%) |
DisputeStatusChanged
Emitted when an IP asset's dispute status changes
event DisputeStatusChanged(uint256 indexed tokenId, bool hasDispute);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IP asset token ID |
hasDispute | bool | Whether the asset now has an active dispute |
LicenseTokenContractSet
Emitted when the LicenseToken contract address is updated
event LicenseTokenContractSet(address indexed newContract);
Parameters
| Name | Type | Description |
|---|---|---|
newContract | address | The new LicenseToken contract address |
ArbitratorContractSet
Emitted when the GovernanceArbitrator contract address is updated
event ArbitratorContractSet(address indexed newContract);
Parameters
| Name | Type | Description |
|---|---|---|
newContract | address | The new GovernanceArbitrator contract address |
RevenueDistributorSet
Emitted when the RevenueDistributor contract address is updated
event RevenueDistributorSet(address indexed newContract);
Parameters
| Name | Type | Description |
|---|---|---|
newContract | address | The new RevenueDistributor contract address |
PrivateMetadataUpdated
Emitted when private metadata is updated for an IP asset
The metadata content is not included in the event for privacy
event PrivateMetadataUpdated(uint256 indexed tokenId);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The ID of the IP asset |
NFTWrapped
Emitted when an NFT is wrapped into an IPAsset
event NFTWrapped(
uint256 indexed ipTokenId, address indexed nftContract, uint256 indexed nftTokenId, address wrapper
);
Parameters
| Name | Type | Description |
|---|---|---|
ipTokenId | uint256 | The newly created IPAsset ID |
nftContract | address | The wrapped NFT contract address |
nftTokenId | uint256 | The wrapped NFT token ID |
wrapper | address | The address that wrapped the NFT |
NFTUnwrapped
Emitted when an IPAsset is unwrapped to retrieve the original NFT
event NFTUnwrapped(
uint256 indexed ipTokenId, address indexed nftContract, uint256 indexed nftTokenId, address owner
);
Parameters
| Name | Type | Description |
|---|---|---|
ipTokenId | uint256 | The burned IPAsset ID |
nftContract | address | The returned NFT contract address |
nftTokenId | uint256 | The returned NFT token ID |
owner | address | The address that received the NFT |
Errors
InvalidAddress
Thrown when attempting to mint to zero address
error InvalidAddress();
InvalidContractAddress
Thrown when setting a contract address to zero address
error InvalidContractAddress(address contractAddress);
Parameters
| Name | Type | Description |
|---|---|---|
contractAddress | address | The invalid address that was attempted |
EmptyMetadata
Thrown when metadata URI is empty
error EmptyMetadata();
NotTokenOwner
Thrown when caller is not the token owner
error NotTokenOwner();
HasActiveLicenses
Thrown when attempting to burn a token with active licenses
error HasActiveLicenses(uint256 tokenId, uint256 count);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IP asset token ID |
count | uint256 | Number of active licenses preventing the burn |
HasActiveDispute
Thrown when attempting to burn a token with an active dispute
error HasActiveDispute(uint256 tokenId);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IP asset token ID |
LicenseCountUnderflow
Thrown when attempting to decrement license count below zero
error LicenseCountUnderflow(uint256 tokenId, uint256 current, uint256 attempted);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The IP asset token ID |
current | uint256 | Current license count |
attempted | uint256 | Amount attempting to decrement |
NotWrappedNFT
Thrown when attempting to unwrap a non-wrapped IPAsset
error NotWrappedNFT();
NFTAlreadyWrapped
Thrown when attempting to wrap an NFT that's already wrapped
error NFTAlreadyWrapped(uint256 existingIPAssetId);
Parameters
| Name | Type | Description |
|---|---|---|
existingIPAssetId | uint256 | The IPAsset that already wraps this NFT |
NFTNotOwned
Thrown when caller doesn't own the NFT being wrapped
error NFTNotOwned(address nftContract, uint256 nftTokenId, address caller);
Parameters
| Name | Type | Description |
|---|---|---|
nftContract | address | The NFT contract address |
nftTokenId | uint256 | The NFT token ID |
caller | address | The address attempting to wrap |
Structs
WrappedNFT
Represents a wrapped NFT within an IPAsset
struct WrappedNFT {
address nftContract;
uint256 nftTokenId;
}
Properties
| Name | Type | Description |
|---|---|---|
nftContract | address | The address of the wrapped ERC721 contract |
nftTokenId | uint256 | The token ID of the wrapped NFT |