forked from storyprotocol/protocol-periphery
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6acb0db
commit 6104913
Showing
10 changed files
with
1,260 additions
and
8 deletions.
There are no files selected for viewing
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,22 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.26; | ||
|
||
/// @title Minimal Soulbound NFT Interface | ||
/// @notice Minimal interface for soulbinding EIP-721 NFTs | ||
interface IERC5192 { | ||
/// @notice Emitted when the locking status is changed to locked. | ||
/// @dev If a token is minted and the status is locked, this event should be emitted. | ||
/// @param tokenId The identifier for a token. | ||
event Locked(uint256 tokenId); | ||
|
||
/// @notice Emitted when the locking status is changed to unlocked. | ||
/// @dev If a token is minted and the status is unlocked, this event should be emitted. | ||
/// @param tokenId The identifier for a token. | ||
event Unlocked(uint256 tokenId); | ||
|
||
/// @notice Returns the locking status of an Soulbound Token | ||
/// @dev SBTs assigned to zero address are considered invalid, and queries | ||
/// about them do throw. | ||
/// @param tokenId The identifier for an SBT. | ||
function locked(uint256 tokenId) 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,67 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.26; | ||
|
||
import { IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; | ||
|
||
/// @title Organization NFT Interface | ||
/// @notice Each organization token represents a Story ecosystem project. | ||
/// The root organization token represents Story. | ||
/// Each organization token register as a IP on Story and is a derivative of the root organization IP. | ||
interface IOrgNFT is IERC721Metadata { | ||
//////////////////////////////////////////////////////////////////////////// | ||
// Errors // | ||
//////////////////////////////////////////////////////////////////////////// | ||
/// @notice Caller is not the StoryNFTFactory contract. | ||
/// @param caller The address of the caller. | ||
/// @param storyNftFactory The address of the `StoryNFTFactory` contract. | ||
error OrgNFT__CallerNotStoryNFTFactory(address caller, address storyNftFactory); | ||
|
||
/// @notice Root organization NFT has already been minted. | ||
error OrgNFT__RootOrgNftAlreadyMinted(); | ||
|
||
/// @notice Root organization NFT has not been minted yet (`mintRootOrgNft` has not been called). | ||
error OrgNFT__RootOrgNftNotMinted(); | ||
|
||
/// @notice Zero address provided as a param to OrgNFT functions. | ||
error OrgNFT__ZeroAddressParam(); | ||
|
||
//////////////////////////////////////////////////////////////////////////// | ||
// Events // | ||
//////////////////////////////////////////////////////////////////////////// | ||
/// @notice Emitted when a organization token minted. | ||
/// @param recipient The address of the recipient of the organization token. | ||
/// @param orgNft The address of the organization NFT. | ||
/// @param tokenId The ID of the minted organization token. | ||
/// @param orgIpId The ID of the organization IP. | ||
event OrgNFTMinted(address recipient, address orgNft, uint256 tokenId, address orgIpId); | ||
|
||
//////////////////////////////////////////////////////////////////////////// | ||
// Functions // | ||
//////////////////////////////////////////////////////////////////////////// | ||
/// @notice Mints the root organization token and register it as an IP. | ||
/// @param recipient The address of the recipient of the root organization token. | ||
/// @param tokenURI The URI of the root organization token. | ||
/// @return rootOrgTokenId The ID of the root organization token. | ||
/// @return rootOrgIpId The ID of the root organization IP. | ||
function mintRootOrgNft( | ||
address recipient, | ||
string memory tokenURI | ||
) external returns (uint256 rootOrgTokenId, address rootOrgIpId); | ||
|
||
/// @notice Mints a organization token, register it as an IP, | ||
/// and makes the IP as a derivative of the root organization IP. | ||
/// @param recipient The address of the recipient of the minted organization token. | ||
/// @param tokenURI The URI of the minted organization token. | ||
/// @return orgTokenId The ID of the minted organization token. | ||
/// @return orgIpId The ID of the organization IP. | ||
function mintOrgNft( | ||
address recipient, | ||
string memory tokenURI | ||
) external returns (uint256 orgTokenId, address orgIpId); | ||
|
||
/// @notice Returns the ID of the root organization IP. | ||
function getRootOrgIpId() external view returns (address); | ||
|
||
/// @notice Returns the total supply of OrgNFT. | ||
function totalSupply() external view returns (uint256); | ||
} |
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,75 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.26; | ||
|
||
import { IERC721Metadata } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; | ||
|
||
import { IERC5192 } from "./IERC5192.sol"; | ||
|
||
/// @title Story Badge NFT Interface | ||
/// @notice A Story Badge NFT is a soulbound NFT that has an unified token URI for all tokens. | ||
interface IStoryBadgeNFT is IERC5192, IERC721Metadata { | ||
//////////////////////////////////////////////////////////////////////////// | ||
// Errors // | ||
//////////////////////////////////////////////////////////////////////////// | ||
/// @notice Invalid whitelist signature. | ||
error StoryBadgeNFT__InvalidSignature(); | ||
|
||
/// @notice The provided whitelist signature is already used. | ||
error StoryBadgeNFT__SignatureAlreadyUsed(); | ||
|
||
/// @notice Badges are soulbound, cannot be transferred. | ||
error StoryBadgeNFT__TransferLocked(); | ||
|
||
/// @notice Zero address provided as a param to StoryBadgeNFT functions. | ||
error StoryBadgeNFT__ZeroAddressParam(); | ||
|
||
//////////////////////////////////////////////////////////////////////////// | ||
// Structs // | ||
//////////////////////////////////////////////////////////////////////////// | ||
/// @notice Struct for initializing the StoryBadgeNFT contract. | ||
/// @param name The name of the collection. | ||
/// @param symbol The symbol of the collection. | ||
/// @param contractURI The contract URI of the collection (follows OpenSea contract-level metadata standard). | ||
/// @param tokenURI The token URI for all the badges (follows OpenSea metadata standard). | ||
/// @param signer The signer of the whitelist signatures. | ||
struct InitParams { | ||
string name; | ||
string symbol; | ||
string contractURI; | ||
string tokenURI; | ||
address signer; | ||
} | ||
|
||
//////////////////////////////////////////////////////////////////////////// | ||
// Events // | ||
//////////////////////////////////////////////////////////////////////////// | ||
/// @notice Emitted when a badge NFT is minted. | ||
/// @param recipient The address of the recipient of the badge NFT. | ||
/// @param tokenId The token ID of the minted badge NFT. | ||
/// @param ipId The ID of the badge NFT IP. | ||
event StoryBadgeNFTMinted(address recipient, uint256 tokenId, address ipId); | ||
|
||
/// @notice Emitted when the signer is updated. | ||
/// @param signer The new signer address. | ||
event StoryBadgeNFTSignerUpdated(address signer); | ||
|
||
//////////////////////////////////////////////////////////////////////////// | ||
// Functions // | ||
//////////////////////////////////////////////////////////////////////////// | ||
/// @notice Mints a badge for the given recipient, registers it as an IP, | ||
/// and makes it a derivative of the organization IP. | ||
/// @param recipient The address of the recipient of the badge NFT. | ||
/// @param signature The signature from the whitelist signer. This signautre is genreated by having the whitelist | ||
/// signer sign the caller's address (msg.sender) for this `mint` function. | ||
/// @return tokenId The token ID of the minted badge NFT. | ||
/// @return ipId The ID of the badge NFT IP. | ||
function mint(address recipient, bytes calldata signature) external returns (uint256 tokenId, address ipId); | ||
|
||
/// @notice Updates the whitelist signer. | ||
/// @param signer_ The new whitelist signer address. | ||
function setSigner(address signer_) external; | ||
|
||
/// @notice Updates the unified token URI for all badges. | ||
/// @param tokenURI_ The new token URI. | ||
function setTokenURI(string memory tokenURI_) external; | ||
} |
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,124 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.26; | ||
|
||
/// @title Story NFT Factory Interface | ||
/// @notice Story NFT Factory is the entrypoint for creating new Story NFT collections. | ||
interface IStoryNFTFactory { | ||
//////////////////////////////////////////////////////////////////////////// | ||
// Errors // | ||
//////////////////////////////////////////////////////////////////////////// | ||
/// @notice Invalid signature provided to StoryNFTFactory functions. | ||
/// @param signature The signature that is invalid. | ||
error StoryNFTFactory__InvalidSignature(bytes signature); | ||
|
||
/// @notice NftTemplate is not whitelisted to be used as a StoryNFT. | ||
/// @param nftTemplate The NFT template that is not whitelisted. | ||
error StoryNFTFactory__NftTemplateNotWhitelisted(address nftTemplate); | ||
|
||
/// @notice Organization is already deployed by the StoryNFTFactory. | ||
/// @param orgName The name of the organization that is already deployed. | ||
/// @param deployedStoryNft The address of the already deployed StoryNFT for the organization. | ||
error StoryNFTFactory__OrgAlreadyDeployed(string orgName, address deployedStoryNft); | ||
|
||
/// @notice Organization is not found in the StoryNFTFactory. | ||
/// @param orgName The name of the organization that is not found. | ||
error StoryNFTFactory__OrgNotFound(string orgName); | ||
|
||
/// @notice Signature is already used to deploy a StoryNFT. | ||
/// @param signature The signature that is already used. | ||
error StoryNFTFactory__SignatureAlreadyUsed(bytes signature); | ||
|
||
/// @notice BaseStoryNFT is not supported by the StoryNFTFactory. | ||
/// @param tokenContract The address of the token contract that does not implement BaseStoryNFT. | ||
error StoryNFTFactory__UnsupportedBaseStoryNFT(address tokenContract); | ||
|
||
/// @notice Zero address provided as a param to StoryNFTFactory functions. | ||
error StoryNFTFactory__ZeroAddressParam(); | ||
|
||
//////////////////////////////////////////////////////////////////////////// | ||
// Events // | ||
//////////////////////////////////////////////////////////////////////////// | ||
/// @notice Emitted when the default StoryNFT template is updated. | ||
/// @param defaultStoryNftTemplate The new default StoryNFT template. | ||
event StoryNFTFactoryDefaultStoryNftTemplateUpdated(address defaultStoryNftTemplate); | ||
|
||
/// @notice Emitted when a new orgnization NFT is minted and a new StoryNFT associated with it is deployed. | ||
/// @param orgName The name of the organization. | ||
/// @param orgNft The address of the organization NFT. | ||
/// @param orgTokenId The token ID of the organization NFT. | ||
/// @param orgIpId The ID of the organization IP. | ||
/// @param storyNft The address of the deployed StoryNFT. | ||
event StoryNftDeployed(string orgName, address orgNft, uint256 orgTokenId, address orgIpId, address storyNft); | ||
|
||
/// @notice Emitted when the signer of the StoryNFTFactory is updated. | ||
/// @param signer The new signer of the StoryNFTFactory. | ||
event StoryNFTFactorySignerUpdated(address signer); | ||
|
||
/// @notice Emitted when a new Story NFT template is whitelisted. | ||
/// @param nftTemplate The new Story NFT template that is whitelisted to be used in StoryNFTFactory. | ||
event StoryNFTFactoryNftTemplateWhitelisted(address nftTemplate); | ||
|
||
//////////////////////////////////////////////////////////////////////////// | ||
// Functions // | ||
//////////////////////////////////////////////////////////////////////////// | ||
/// @notice Mints a new organization NFT and deploys (creates a clone of) `storyNftTemplate` as the StoryNFT | ||
/// associated with the new organization NFT. | ||
/// @param storyNftTemplate The address of a whitelisted StoryNFT template to be cloned. | ||
/// @param storyNftOwner The address of the owner of the new StoryNFT contract. | ||
/// @param orgName The name of the organization. | ||
/// @param orgTokenURI The token URI of the organization NFT. | ||
/// @param signature The signature from the StoryNFTFactory's whitelist signer. This signautre is genreated by | ||
/// having the whitelist signer sign the caller's address (msg.sender) for this `deployStoryNft` function. | ||
/// @param initData The initialization data for the StoryNFT (see {IStoryBadgeNFT-InitParams} for an example). | ||
/// @return orgTokenId The token ID of the organization NFT. | ||
/// @return orgIpId The ID of the organization IP. | ||
/// @return storyNft The address of the dployed StoryNFT | ||
function deployStoryNft( | ||
address storyNftTemplate, | ||
address storyNftOwner, | ||
string calldata orgName, | ||
string calldata orgTokenURI, | ||
bytes calldata signature, | ||
bytes calldata initData | ||
) external returns (uint256 orgTokenId, address orgIpId, address storyNft); | ||
|
||
/// @notice Mints a new organization NFT and deploys (creates a clone of) `storyNftTemplate` as the StoryNFT | ||
/// associated with the new organization NFT. | ||
/// @dev Enforced to be only callable by the protocol admin in governance. | ||
/// @param storyNftTemplate The address of a whitelisted StoryNFT template to be cloned. | ||
/// @param storyNftOwner The address of the owner of the new StoryNFT contract. | ||
/// @param orgName The name of the organization. | ||
/// @param orgTokenURI The token URI of the organization NFT. | ||
/// @param initData The initialization data for the StoryNFT (see {IStoryBadgeNFT-InitParams} for an example). | ||
/// @param isRootOrg Whether the organization is the root organization. | ||
/// @return orgTokenId The token ID of the organization NFT. | ||
/// @return orgIpId The ID of the organization IP. | ||
/// @return storyNft The address of the dployed StoryNFT | ||
function deployStoryNftByAdmin( | ||
address storyNftTemplate, | ||
address storyNftOwner, | ||
string calldata orgName, | ||
string calldata orgTokenURI, | ||
bytes calldata initData, | ||
bool isRootOrg | ||
) external returns (uint256 orgTokenId, address orgIpId, address storyNft); | ||
|
||
/// @notice Sets the default StoryNFT template of the StoryNFTFactory. | ||
/// @param defaultStoryNftTemplate The new default StoryNFT template. | ||
function setDefaultStoryNftTemplate(address defaultStoryNftTemplate) external; | ||
|
||
/// @notice Sets the signer of the StoryNFTFactory. | ||
/// @param signer The new signer of the StoryNFTFactory. | ||
function setSigner(address signer) external; | ||
|
||
/// @notice Whitelists a new StoryNFT template. | ||
/// @param storyNftTemplate The new StoryNFT template to be whitelisted. | ||
function whitelistNftTemplate(address storyNftTemplate) external; | ||
|
||
/// @notice Returns the default StoryNFT template address. | ||
function getDefaultStoryNftTemplate() external view returns (address); | ||
|
||
/// @notice Returns the address of the StoryNFT for a given organization name. | ||
/// @param orgName The name of the organization. | ||
function getStoryNftAddress(string calldata orgName) external view returns (address); | ||
} |
Oops, something went wrong.