Skip to content

Commit

Permalink
Refactor OrgStoryNFTFactory Contract to Reduce Code Redundancy
Browse files Browse the repository at this point in the history
  • Loading branch information
lukema95 committed Jan 4, 2025
1 parent 01a2dee commit 53a11bf
Showing 1 changed file with 72 additions and 71 deletions.
143 changes: 72 additions & 71 deletions contracts/story-nft/OrgStoryNFTFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -131,46 +131,15 @@ contract OrgStoryNFTFactory is IOrgStoryNFTFactory, AccessManagedUpgradeable, UU
bytes calldata signature,
IStoryNFT.StoryNftInitParams calldata storyNftInitParams
) external returns (address orgNft, uint256 orgTokenId, address orgIpId, address orgStoryNft) {
OrgStoryNFTFactoryStorage storage $ = _getOrgStoryNFTFactoryStorage();

// The given story NFT template must be whitelisted
if (!$.whitelistedNftTemplates[orgStoryNftTemplate])
revert OrgStoryNFTFactory__NftTemplateNotWhitelisted(orgStoryNftTemplate);

// The given signature must not have been used
if ($.usedSignatures[signature]) revert OrgStoryNFTFactory__SignatureAlreadyUsed(signature);

// Mark the signature as used
$.usedSignatures[signature] = true;

// The given organization name must not have been used
if ($.deployedOrgStoryNftsByOrgName[orgName] != address(0))
revert OrgStoryNFTFactory__OrgAlreadyDeployed(orgName, $.deployedOrgStoryNftsByOrgName[orgName]);

// The signature must be valid
bytes32 hash = keccak256(abi.encodePacked(msg.sender)).toEthSignedMessageHash();
if (!SignatureChecker.isValidSignatureNow($.signer, hash, signature))
revert OrgStoryNFTFactory__InvalidSignature(signature);

// Mint the organization NFT and register it as an IP
(orgTokenId, orgIpId) = ORG_NFT.mintOrgNft(orgNftRecipient, orgIpMetadata);

orgNft = address(ORG_NFT);

// Creates a new BeaconProxy for the story NFT template and initializes it
orgStoryNft = address(
new BeaconProxy(
IOrgStoryNFT(orgStoryNftTemplate).getBeacon(),
abi.encodeWithSelector(IOrgStoryNFT.initialize.selector, orgTokenId, orgIpId, storyNftInitParams)
)
_validateSignature(signature);
(orgNft, orgTokenId, orgIpId, orgStoryNft) = _deployOrgStoryNft(
orgStoryNftTemplate,
orgNftRecipient,
orgName,
orgIpMetadata,
storyNftInitParams,
false
);

// Stores the deployed story NFT address
$.deployedOrgStoryNftsByOrgName[orgName] = orgStoryNft;
$.deployedOrgStoryNftsByOrgTokenId[orgTokenId] = orgStoryNft;
$.deployedOrgStoryNftsByOrgIpId[orgIpId] = orgStoryNft;

emit OrgStoryNftDeployed(orgName, orgNft, orgTokenId, orgIpId, orgStoryNft);
}

/// @notice Mints a new organization NFT and deploys a proxy to `orgStoryNftTemplate` as the OrgStoryNFT
Expand All @@ -194,39 +163,14 @@ contract OrgStoryNFTFactory is IOrgStoryNFTFactory, AccessManagedUpgradeable, UU
IStoryNFT.StoryNftInitParams calldata storyNftInitParams,
bool isRootOrg
) external restricted returns (address orgNft, uint256 orgTokenId, address orgIpId, address orgStoryNft) {
OrgStoryNFTFactoryStorage storage $ = _getOrgStoryNFTFactoryStorage();

// The given story NFT template must be whitelisted
if (!$.whitelistedNftTemplates[orgStoryNftTemplate])
revert OrgStoryNFTFactory__NftTemplateNotWhitelisted(orgStoryNftTemplate);

// The given organization name must not have been used
if ($.deployedOrgStoryNftsByOrgName[orgName] != address(0))
revert OrgStoryNFTFactory__OrgAlreadyDeployed(orgName, $.deployedOrgStoryNftsByOrgName[orgName]);

// Mint the organization NFT and register it as an IP
if (isRootOrg) {
(orgTokenId, orgIpId) = ORG_NFT.mintRootOrgNft(orgNftRecipient, orgIpMetadata);
} else {
(orgTokenId, orgIpId) = ORG_NFT.mintOrgNft(orgNftRecipient, orgIpMetadata);
}

orgNft = address(ORG_NFT);

// Creates a new BeaconProxy for the story NFT template and initializes it
orgStoryNft = address(
new BeaconProxy(
IOrgStoryNFT(orgStoryNftTemplate).getBeacon(),
abi.encodeWithSelector(IOrgStoryNFT.initialize.selector, orgTokenId, orgIpId, storyNftInitParams)
)
(orgNft, orgTokenId, orgIpId, orgStoryNft) = _deployOrgStoryNft(
orgStoryNftTemplate,
orgNftRecipient,
orgName,
orgIpMetadata,
storyNftInitParams,
isRootOrg
);

// Stores the deployed story NFT address
$.deployedOrgStoryNftsByOrgName[orgName] = orgStoryNft;
$.deployedOrgStoryNftsByOrgTokenId[orgTokenId] = orgStoryNft;
$.deployedOrgStoryNftsByOrgIpId[orgIpId] = orgStoryNft;

emit OrgStoryNftDeployed(orgName, orgNft, orgTokenId, orgIpId, orgStoryNft);
}

/// @notice Sets the default StoryNFT template of the OrgStoryNFTFactory.
Expand Down Expand Up @@ -297,6 +241,63 @@ contract OrgStoryNFTFactory is IOrgStoryNFTFactory, AccessManagedUpgradeable, UU
return _getOrgStoryNFTFactoryStorage().whitelistedNftTemplates[nftTemplate];
}

function _validateSignature(bytes calldata signature) private {
OrgStoryNFTFactoryStorage storage $ = _getOrgStoryNFTFactoryStorage();

// The given signature must not have been used
if ($.usedSignatures[signature]) revert OrgStoryNFTFactory__SignatureAlreadyUsed(signature);

// Mark the signature as used
$.usedSignatures[signature] = true;

bytes32 hash = keccak256(abi.encodePacked(msg.sender)).toEthSignedMessageHash();
if (!SignatureChecker.isValidSignatureNow($.signer, hash, signature))
revert OrgStoryNFTFactory__InvalidSignature(signature);
}

function _deployOrgStoryNft(
address orgStoryNftTemplate,
address orgNftRecipient,
string calldata orgName,
WorkflowStructs.IPMetadata calldata orgIpMetadata,
IStoryNFT.StoryNftInitParams calldata storyNftInitParams,
bool isRootOrg
) private returns (address orgNft, uint256 orgTokenId, address orgIpId, address orgStoryNft) {
OrgStoryNFTFactoryStorage storage $ = _getOrgStoryNFTFactoryStorage();

// The given story NFT template must be whitelisted
if (!$.whitelistedNftTemplates[orgStoryNftTemplate])
revert OrgStoryNFTFactory__NftTemplateNotWhitelisted(orgStoryNftTemplate);

// The given organization name must not have been used
if ($.deployedOrgStoryNftsByOrgName[orgName] != address(0))
revert OrgStoryNFTFactory__OrgAlreadyDeployed(orgName, $.deployedOrgStoryNftsByOrgName[orgName]);

// Mint the organization NFT and register it as an IP
if (isRootOrg) {
(orgTokenId, orgIpId) = ORG_NFT.mintRootOrgNft(orgNftRecipient, orgIpMetadata);
} else {
(orgTokenId, orgIpId) = ORG_NFT.mintOrgNft(orgNftRecipient, orgIpMetadata);
}

orgNft = address(ORG_NFT);

// Creates a new BeaconProxy for the story NFT template and initializes it
orgStoryNft = address(
new BeaconProxy(
IOrgStoryNFT(orgStoryNftTemplate).getBeacon(),
abi.encodeWithSelector(IOrgStoryNFT.initialize.selector, orgTokenId, orgIpId, storyNftInitParams)
)
);

// Stores the deployed story NFT address
$.deployedOrgStoryNftsByOrgName[orgName] = orgStoryNft;
$.deployedOrgStoryNftsByOrgTokenId[orgTokenId] = orgStoryNft;
$.deployedOrgStoryNftsByOrgIpId[orgIpId] = orgStoryNft;

emit OrgStoryNftDeployed(orgName, orgNft, orgTokenId, orgIpId, orgStoryNft);
}

/// @dev Returns the storage struct of OrgStoryNFTFactory.
function _getOrgStoryNFTFactoryStorage() private pure returns (OrgStoryNFTFactoryStorage storage $) {
assembly {
Expand Down

0 comments on commit 53a11bf

Please sign in to comment.