Skip to content

Commit

Permalink
fix(grouping): deploy vault for IP if no vault (#105)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebsadface authored Oct 22, 2024
1 parent cd25593 commit 1474b40
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 29 deletions.
4 changes: 2 additions & 2 deletions contracts/interfaces/workflows/IGroupingWorkflows.sol
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ interface IGroupingWorkflows {
) external returns (address groupId);

/// @notice Collect royalties for the entire group and distribute the rewards to each member IP's royalty vault
/// @param groupId The ID of the group IP.
/// @param groupIpId The ID of the group IP.
/// @param currencyTokens The addresses of the currency (revenue) tokens to claim.
/// @param groupSnapshotIds The IDs of the snapshots to collect royalties on.
/// @param memberIpIds The IDs of the member IPs to distribute the rewards to.
/// @return collectedRoyalties The amounts of royalties collected for each currency token.
function collectRoyaltiesAndClaimReward(
address groupId,
address groupIpId,
address[] calldata currencyTokens,
uint256[] calldata groupSnapshotIds,
address[] calldata memberIpIds
Expand Down
40 changes: 33 additions & 7 deletions contracts/workflows/GroupingWorkflows.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ICoreMetadataModule } from "@storyprotocol/core/interfaces/modules/meta
import { IGroupingModule } from "@storyprotocol/core/interfaces/modules/grouping/IGroupingModule.sol";
import { ILicensingModule } from "@storyprotocol/core/interfaces/modules/licensing/ILicensingModule.sol";
import { GroupNFT } from "@storyprotocol/core/GroupNFT.sol";
import { RoyaltyModule } from "@storyprotocol/core/modules/royalty/RoyaltyModule.sol";

import { BaseWorkflow } from "../BaseWorkflow.sol";
import { Errors } from "../lib/Errors.sol";
Expand Down Expand Up @@ -51,6 +52,9 @@ contract GroupingWorkflows is
/// @notice The address of the Group NFT contract.
GroupNFT public immutable GROUP_NFT;

/// @notice The address of the Royalty Module.
RoyaltyModule public immutable ROYALTY_MODULE;

/// @custom:oz-upgrades-unsafe-allow constructor
constructor(
address accessController,
Expand All @@ -60,7 +64,8 @@ contract GroupingWorkflows is
address ipAssetRegistry,
address licenseRegistry,
address licensingModule,
address pilTemplate
address pilTemplate,
address royaltyModule
)
BaseWorkflow(
accessController,
Expand All @@ -79,12 +84,13 @@ contract GroupingWorkflows is
ipAssetRegistry == address(0) ||
licenseRegistry == address(0) ||
licensingModule == address(0) ||
pilTemplate == address(0)
pilTemplate == address(0) ||
royaltyModule == address(0)
) revert Errors.GroupingWorkflows__ZeroAddressParam();

GROUPING_MODULE = IGroupingModule(groupingModule);
GROUP_NFT = GroupNFT(groupNft);

ROYALTY_MODULE = RoyaltyModule(royaltyModule);
_disableInitializers();
}

Expand Down Expand Up @@ -275,22 +281,42 @@ contract GroupingWorkflows is
}

/// @notice Collect royalties for the entire group and distribute the rewards to each member IP's royalty vault
/// @param groupId The ID of the group IP.
/// @param groupIpId The ID of the group IP.
/// @param currencyTokens The addresses of the currency (revenue) tokens to claim.
/// @param groupSnapshotIds The IDs of the snapshots to collect royalties on.
/// @param memberIpIds The IDs of the member IPs to distribute the rewards to.
/// @return collectedRoyalties The amounts of royalties collected for each currency token.
function collectRoyaltiesAndClaimReward(
address groupId,
address groupIpId,
address[] calldata currencyTokens,
uint256[] calldata groupSnapshotIds,
address[] calldata memberIpIds
) external returns (uint256[] memory collectedRoyalties) {
(address groupLicenseTemplate, uint256 groupLicenseTermsId) = LICENSE_REGISTRY.getAttachedLicenseTerms(
groupIpId,
0
);
for (uint256 i = 0; i < memberIpIds.length; i++) {
// check if given member IPs already have a royalty vault
if (ROYALTY_MODULE.ipRoyaltyVaults(memberIpIds[i]) == address(0)) {
// mint license tokens to the member IPs if they don't have a royalty vault
LICENSING_MODULE.mintLicenseTokens({
licensorIpId: memberIpIds[i],
licenseTemplate: groupLicenseTemplate,
licenseTermsId: groupLicenseTermsId,
amount: 1,
receiver: msg.sender,
royaltyContext: "",
maxMintingFee: 0
});
}
}

collectedRoyalties = new uint256[](currencyTokens.length);
for (uint256 i = 0; i < currencyTokens.length; i++) {
if (currencyTokens[i] == address(0)) revert Errors.GroupingWorkflows__ZeroAddressParam();
collectedRoyalties[i] = GROUPING_MODULE.collectRoyalties(groupId, currencyTokens[i], groupSnapshotIds);
GROUPING_MODULE.claimReward(groupId, currencyTokens[i], memberIpIds);
collectedRoyalties[i] = GROUPING_MODULE.collectRoyalties(groupIpId, currencyTokens[i], groupSnapshotIds);
GROUPING_MODULE.claimReward(groupIpId, currencyTokens[i], memberIpIds);
}
}

Expand Down
3 changes: 2 additions & 1 deletion script/upgrade/UpgradeGroupingWorkflows.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ contract UpgradeGroupingWorkflows is UpgradeHelper {
ipAssetRegistryAddr,
licenseRegistryAddr,
licensingModuleAddr,
pilTemplateAddr
pilTemplateAddr,
royaltyModuleAddr
)
);
console2.log("New GroupingWorkflows Implementation: ", newGroupingWorkflowsImpl);
Expand Down
3 changes: 2 additions & 1 deletion script/utils/DeployHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,8 @@ contract DeployHelper is
ipAssetRegistryAddr,
licenseRegistryAddr,
licensingModuleAddr,
pilTemplateAddr
pilTemplateAddr,
royaltyModuleAddr
)
);
groupingWorkflows = GroupingWorkflows(
Expand Down
2 changes: 1 addition & 1 deletion test/workflows/DerivativeWorkflows.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ contract DerivativeWorkflowsTest is BaseTest {
terms: PILFlavors.commercialRemix({
mintingFee: 100 * 10 ** mockToken.decimals(),
commercialRevShare: 10, // 1%
royaltyPolicy: address(royaltyPolicyLAP),
royaltyPolicy: address(royaltyPolicyLRP),
currencyToken: address(mockToken)
})
});
Expand Down
17 changes: 0 additions & 17 deletions test/workflows/GroupingWorkflows.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -334,23 +334,6 @@ contract GroupingWorkflowsTest is BaseTest {
snapshotIds[1] = snapshotId2;
royaltyTokens[0] = address(mockToken);

{
/* TODO: This is a workaround to avoid the error where the member IP's IP royalty vault is not initialized
* when claiming reward. remove this when the issue is fixed in core protocol.
*/
for (uint256 i = 0; i < ipIds.length; i++) {
licensingModule.mintLicenseTokens({
licensorIpId: ipIds[i],
licenseTemplate: address(pilTemplate),
licenseTermsId: testLicenseTermsId,
amount: 1,
receiver: u.admin,
royaltyContext: "",
maxMintingFee: 0
});
}
}

uint256[] memory collectedRoyalties = groupingWorkflows.collectRoyaltiesAndClaimReward(
newGroupId,
royaltyTokens,
Expand Down

0 comments on commit 1474b40

Please sign in to comment.