From bf967975161560a215c4f55cf2f405cc6f84a399 Mon Sep 17 00:00:00 2001 From: Aleksejs Uzans <103576418+Aleksejs0585@users.noreply.github.com> Date: Mon, 30 Dec 2024 17:25:51 +0200 Subject: [PATCH 1/3] Update royalty.test.ts Here is a refactored version of the code. Repeated logic has been extracted into utility functions to reduce redundancy and improve readability. --- test/hardhat/e2e/royalty/royalty.test.ts | 377 ++++------------------- 1 file changed, 58 insertions(+), 319 deletions(-) diff --git a/test/hardhat/e2e/royalty/royalty.test.ts b/test/hardhat/e2e/royalty/royalty.test.ts index 042916019..c0bcd5df3 100644 --- a/test/hardhat/e2e/royalty/royalty.test.ts +++ b/test/hardhat/e2e/royalty/royalty.test.ts @@ -8,329 +8,68 @@ import { mintNFTAndRegisterIPA } from "../utils/mintNFTAndRegisterIPA"; import { terms } from "../licenseTermsTemplate"; describe("RoyaltyModule", function () { - let signers:any; - let ipId1: any; - let ipId2: any; - let ipId3: any; - let ipId4: any; - let licenseTermsLAPId: any; - let licenseTermsLRPId: any; - let user1ConnectedLicensingModule: any; - let user2ConnectedLicensingModule: any; - let user3ConnectedLicensingModule: any; - let user1ConnectedRoyaltyModule: any; - let user2ConnectedRoyaltyModule: any; - let user3ConnectedRoyaltyModule: any; - let user2ConnectedRoyaltyPolicyLAP: any; - let user2ConnectedRoyaltyPolicyLRP: any; - let user3ConnectedRoyaltyPolicyLRP: any; - const testTerms = terms; - - this.beforeAll("Get Signers and register license terms", async function () { - // Get the signers - signers = await hre.ethers.getSigners(); - - // Register a commericial remix license with royalty policy LAP - testTerms.royaltyPolicy = RoyaltyPolicyLAP; - testTerms.defaultMintingFee = 100; - testTerms.commercialUse = true; - testTerms.derivativesReciprocal = true; - testTerms.commercialRevShare = 10 * 10 ** 6; - testTerms.currency = MockERC20; - - const connectedLicense = this.licenseTemplate.connect(signers[0]); - const registerLicenseLAPTx = await expect( - connectedLicense.registerLicenseTerms(testTerms) - ).to.not.be.rejectedWith(Error); - await registerLicenseLAPTx.wait(); - - console.log("Transaction hash: ", registerLicenseLAPTx.hash); - expect(registerLicenseLAPTx.hash).not.to.be.empty.and.to.be.a("HexString"); - - licenseTermsLAPId = await connectedLicense.getLicenseTermsId(terms); - console.log("licenseTermsLAPId: ", licenseTermsLAPId); - - testTerms.royaltyPolicy = RoyaltyPolicyLRP; - const registerLicenseLRPTx = await expect( - connectedLicense.registerLicenseTerms(testTerms) - ).to.not.be.rejectedWith(Error); - await registerLicenseLRPTx.wait(); - - console.log("Transaction hash: ", registerLicenseLRPTx.hash); - expect(registerLicenseLRPTx.hash).not.to.be.empty.and.to.be.a("HexString"); - - licenseTermsLRPId = await connectedLicense.getLicenseTermsId(terms); - console.log("licenseTermsLRPId: ", licenseTermsLRPId); - - user1ConnectedLicensingModule = this.licensingModule.connect(signers[0]); - user2ConnectedLicensingModule = this.licensingModule.connect(signers[1]); - user3ConnectedLicensingModule = this.licensingModule.connect(signers[2]); - user1ConnectedRoyaltyModule = this.royaltyModule.connect(signers[0]); - user2ConnectedRoyaltyModule = this.royaltyModule.connect(signers[1]); - user3ConnectedRoyaltyModule = this.royaltyModule.connect(signers[2]); - user2ConnectedRoyaltyPolicyLAP = this.royaltyPolicyLAP.connect(signers[1]); - user2ConnectedRoyaltyPolicyLRP = this.royaltyPolicyLRP.connect(signers[1]); - user3ConnectedRoyaltyPolicyLRP = this.royaltyPolicyLRP.connect(signers[2]); - }); - - it("Transfer LAP related inflows from royalty policy contract", async function () { - const mintingFee = terms.defaultMintingFee; - const payAmount = 1000 as number; - const commercialRevShare = terms.commercialRevShare / 10 ** 6 / 100; - - const mintAndRegisterResp1 = await mintNFTAndRegisterIPA(signers[0], signers[0]); - ipId1 = mintAndRegisterResp1.ipId; - const mintAndRegisterResp2 = await mintNFTAndRegisterIPA(signers[1], signers[1]); - ipId2 = mintAndRegisterResp2.ipId; - const mintAndRegisterResp3 = await mintNFTAndRegisterIPA(signers[2], signers[2]); - ipId3 = mintAndRegisterResp3.ipId; - - // IP1 attach the commercial remix license - const attachLicenseTx = await expect( - user1ConnectedLicensingModule.attachLicenseTerms(ipId1, PILicenseTemplate, licenseTermsLAPId) - ).not.to.be.rejectedWith(Error); - await attachLicenseTx.wait(); - console.log("Attach license transaction hash: ", attachLicenseTx.hash); - expect(attachLicenseTx.hash).to.not.be.empty.and.to.be.a("HexString"); - - // IP2 is registered as IP1's derivative - const registerDerivative1Tx = await expect( - user2ConnectedLicensingModule.registerDerivative(ipId2, [ipId1], [licenseTermsLAPId], PILicenseTemplate, hre.ethers.ZeroAddress, 0, 0) - ).not.to.be.rejectedWith(Error); - await registerDerivative1Tx.wait(); - console.log("Register derivative transaction hash: ", registerDerivative1Tx.hash); - expect(registerDerivative1Tx.hash).to.not.be.empty.and.to.be.a("HexString"); - - // IP3 is registered as IP2's derivative - const registerDerivative2Tx = await expect( - user3ConnectedLicensingModule.registerDerivative(ipId3, [ipId2], [licenseTermsLAPId], PILicenseTemplate, hre.ethers.ZeroAddress, 0, 0) - ).not.to.be.rejectedWith(Error); - await registerDerivative2Tx.wait(); - console.log("Register derivative transaction hash: ", registerDerivative2Tx.hash); - expect(registerDerivative2Tx.hash).to.not.be.empty.and.to.be.a("HexString"); - - // IP3 payRoyaltyOnBehalf to IP2 - const payRoyaltyOnBehalfTx = await expect( - user3ConnectedRoyaltyModule.payRoyaltyOnBehalf(ipId2, ipId3, MockERC20, BigInt(payAmount)) - ).not.to.be.rejectedWith(Error); - await payRoyaltyOnBehalfTx.wait(); - console.log("Pay royalty on behalf transaction hash: ", payRoyaltyOnBehalfTx.hash); - expect(payRoyaltyOnBehalfTx.hash).to.not.be.empty.and.to.be.a("HexString"); - - // IP2 transferToVault - const transferToVaultTx1 = await expect( - user2ConnectedRoyaltyPolicyLAP.transferToVault(ipId2, ipId1, MockERC20) - ).not.to.be.rejectedWith(Error); - await transferToVaultTx1.wait(); - console.log("Transfer to vault transaction hash: ", transferToVaultTx1.hash); - expect(transferToVaultTx1.hash).to.not.be.empty.and.to.be.a("HexString"); - - const ip2VaultAddress = await user2ConnectedRoyaltyModule.ipRoyaltyVaults(ipId2); - console.log("IP2's ipVaultAddress: ", ip2VaultAddress); - - const ip2RoyaltyVaultAddress = await hre.ethers.getContractAt("IpRoyaltyVault", ip2VaultAddress); - - const ip1VaultAddress = await user1ConnectedRoyaltyModule.ipRoyaltyVaults(ipId1); - console.log("IP1's ipVaultAddress: ", ip1VaultAddress); - - const ip1RoyaltyVaultAddress = await hre.ethers.getContractAt("IpRoyaltyVault", ip1VaultAddress); - - // check claimable revenue - const ip2ClaimableRevenue = await expect( - ip2RoyaltyVaultAddress.claimableRevenue(ipId2, MockERC20) - ).not.to.be.rejectedWith(Error); - console.log("IP2's claimableRevenue: ", ip2ClaimableRevenue); - expect(ip2ClaimableRevenue).to.be.a("BigInt").and.equal(BigInt((payAmount + mintingFee) * (1 - commercialRevShare))); - - // check claimable revenue - const ip1ClaimableRevenue = await expect( - ip1RoyaltyVaultAddress.claimableRevenue(ipId1, MockERC20) - ).not.to.be.rejectedWith(Error); - console.log("IP1's claimableRevenue: ", ip1ClaimableRevenue); - expect(ip1ClaimableRevenue).to.be.a("BigInt").and.equal(BigInt(mintingFee +(payAmount + mintingFee) * commercialRevShare)); - - // claimRevenueOnBehalf - const ip2ClaimRevenueOnBehalfTx = await expect( - ip2RoyaltyVaultAddress.claimRevenueOnBehalf(ipId2, MockERC20) - ).not.to.be.rejectedWith(Error); - await ip2ClaimRevenueOnBehalfTx.wait(); - console.log("Claim revenue on behalf transaction hash: ", ip2ClaimRevenueOnBehalfTx.hash); - expect(ip2ClaimRevenueOnBehalfTx.hash).to.not.be.empty.and.to.be.a("HexString"); - - // claimRevenueOnBehalf - const ip1ClaimRevenueOnBehalfTx = await expect( - ip1RoyaltyVaultAddress.claimRevenueOnBehalf(ipId1, MockERC20) - ).not.to.be.rejectedWith(Error); - await ip1ClaimRevenueOnBehalfTx.wait(); - console.log("Claim revenue on behalf transaction hash: ", ip1ClaimRevenueOnBehalfTx.hash); - expect(ip1ClaimRevenueOnBehalfTx.hash).to.not.be.empty.and.to.be.a("HexString"); - }); - - it("Transfer LRP related inflows from royalty policy contract", async function () { - const mintingFee = terms.defaultMintingFee; - console.log("mintingFee: ", mintingFee); - - const payAmount = 1000 as number; - const commercialRevShare = terms.commercialRevShare / 10 ** 6 / 100; - console.log("commercialRevShare: ", commercialRevShare); - - const mintAndRegisterResp1 = await mintNFTAndRegisterIPA(signers[0], signers[0]); - ipId1 = mintAndRegisterResp1.ipId; - const mintAndRegisterResp2 = await mintNFTAndRegisterIPA(signers[1], signers[1]); - ipId2 = mintAndRegisterResp2.ipId; - const mintAndRegisterResp3 = await mintNFTAndRegisterIPA(signers[2], signers[2]); - ipId3 = mintAndRegisterResp3.ipId; - const mintAndRegisterResp4 = await mintNFTAndRegisterIPA(signers[2], signers[2]); - ipId4 = mintAndRegisterResp4.ipId; - - // IP1 attach the commercial remix license - const attachLicenseTx = await expect( - user1ConnectedLicensingModule.attachLicenseTerms(ipId1, PILicenseTemplate, licenseTermsLRPId) - ).not.to.be.rejectedWith(Error); - await attachLicenseTx.wait(); - console.log("Attach license transaction hash: ", attachLicenseTx.hash); - expect(attachLicenseTx.hash).to.not.be.empty.and.to.be.a("HexString"); - - // IP2 is registered as IP1's derivative - const registerDerivative1Tx = await expect( - user2ConnectedLicensingModule.registerDerivative(ipId2, [ipId1], [licenseTermsLRPId], PILicenseTemplate, hre.ethers.ZeroAddress, 0, 0) - ).not.to.be.rejectedWith(Error); - await registerDerivative1Tx.wait(); - console.log("Register derivative transaction hash: ", registerDerivative1Tx.hash); - expect(registerDerivative1Tx.hash).to.not.be.empty.and.to.be.a("HexString"); - - // IP3 is registered as IP2's derivative - const registerDerivative2Tx = await expect( - user3ConnectedLicensingModule.registerDerivative(ipId3, [ipId2], [licenseTermsLRPId], PILicenseTemplate, hre.ethers.ZeroAddress, 0, 0) - ).not.to.be.rejectedWith(Error); - await registerDerivative2Tx.wait(); - console.log("Register derivative transaction hash: ", registerDerivative2Tx.hash); - expect(registerDerivative2Tx.hash).to.not.be.empty.and.to.be.a("HexString"); - - // IP4 payRoyaltyOnBehalf to IP3 - const payRoyaltyOnBehalfTx = await expect( - user3ConnectedRoyaltyModule.payRoyaltyOnBehalf(ipId3, ipId4, MockERC20, BigInt(payAmount)) - ).not.to.be.rejectedWith(Error); - await payRoyaltyOnBehalfTx.wait(); - console.log("Pay royalty on behalf transaction hash: ", payRoyaltyOnBehalfTx.hash); - expect(payRoyaltyOnBehalfTx.hash).to.not.be.empty.and.to.be.a("HexString"); - - // IP3 transferToVault - const transferToVaultTx1 = await expect( - user3ConnectedRoyaltyPolicyLRP.transferToVault(ipId3, ipId2, MockERC20) - ).not.to.be.rejectedWith(Error); - await transferToVaultTx1.wait(); - console.log("Transfer to vault transaction hash: ", transferToVaultTx1.hash); - expect(transferToVaultTx1.hash).to.not.be.empty.and.to.be.a("HexString"); - - // IP2 transferToVault - const transferToVaultTx2 = await expect( - user2ConnectedRoyaltyPolicyLRP.transferToVault(ipId2, ipId1, MockERC20) - ).not.to.be.rejectedWith(Error); - await transferToVaultTx2.wait(); - console.log("Transfer to vault transaction hash: ", transferToVaultTx2.hash); - expect(transferToVaultTx2.hash).to.not.be.empty.and.to.be.a("HexString"); - - const ip3VaultAddress = await user3ConnectedRoyaltyModule.ipRoyaltyVaults(ipId3); - console.log("IP3's ipVaultAddress: ", ip3VaultAddress); - const ip3RoyaltyVaultAddress = await hre.ethers.getContractAt("IpRoyaltyVault", ip3VaultAddress); - - const ip2VaultAddress = await user2ConnectedRoyaltyModule.ipRoyaltyVaults(ipId2); - console.log("IP2's ipVaultAddress: ", ip2VaultAddress); - const ip2RoyaltyVaultAddress = await hre.ethers.getContractAt("IpRoyaltyVault", ip2VaultAddress); - - const ip1VaultAddress = await user1ConnectedRoyaltyModule.ipRoyaltyVaults(ipId1); - console.log("IP1's ipVaultAddress: ", ip1VaultAddress); - const ip1RoyaltyVaultAddress = await hre.ethers.getContractAt("IpRoyaltyVault", ip1VaultAddress); - - // check claimable revenue - const ip3ClaimableRevenue = await expect( - ip3RoyaltyVaultAddress.claimableRevenue(ipId3, MockERC20) - ).not.to.be.rejectedWith(Error); - console.log("IP3's claimableRevenue: ", ip3ClaimableRevenue); - expect(ip3ClaimableRevenue).to.be.a("BigInt").and.equal(BigInt(payAmount * (1 - commercialRevShare))); - - // check claimable revenue - const ip2ClaimableRevenue = await expect( - ip2RoyaltyVaultAddress.claimableRevenue(ipId2, MockERC20) - ).not.to.be.rejectedWith(Error); - console.log("IP2's claimableRevenue: ", ip2ClaimableRevenue); - expect(ip2ClaimableRevenue).to.be.a("BigInt").and.equal(BigInt(mintingFee * (1 - commercialRevShare) + payAmount * commercialRevShare)); - - // check claimable revenue - const ip1ClaimableRevenue = await expect( - ip1RoyaltyVaultAddress.claimableRevenue(ipId1, MockERC20) - ).not.to.be.rejectedWith(Error); - console.log("IP1's claimableRevenue: ", ip1ClaimableRevenue); - expect(ip1ClaimableRevenue).to.be.a("BigInt").and.equal(BigInt(mintingFee + mintingFee * commercialRevShare)); - - // claimRevenueOnBehalf - const ip3ClaimRevenueOnBehalfTx = await expect( - ip3RoyaltyVaultAddress.claimRevenueOnBehalf(ipId3, MockERC20) - ).not.to.be.rejectedWith(Error); - await ip3ClaimRevenueOnBehalfTx.wait(); - console.log("Claim revenue on behalf transaction hash: ", ip3ClaimRevenueOnBehalfTx.hash); - expect(ip3ClaimRevenueOnBehalfTx.hash).to.not.be.empty.and.to.be.a("HexString"); - - // claimRevenueOnBehalf - const ip2ClaimRevenueOnBehalfTx = await expect( - ip2RoyaltyVaultAddress.claimRevenueOnBehalf(ipId2, MockERC20) - ).not.to.be.rejectedWith(Error); - await ip2ClaimRevenueOnBehalfTx.wait(); - console.log("Claim revenue on behalf transaction hash: ", ip2ClaimRevenueOnBehalfTx.hash); - expect(ip2ClaimRevenueOnBehalfTx.hash).to.not.be.empty.and.to.be.a("HexString"); - - // claimRevenueOnBehalf - const ip1ClaimRevenueOnBehalfTx = await expect( - ip1RoyaltyVaultAddress.claimRevenueOnBehalf(ipId1, MockERC20) - ).not.to.be.rejectedWith(Error); - await ip1ClaimRevenueOnBehalfTx.wait(); - console.log("Claim revenue on behalf transaction hash: ", ip1ClaimRevenueOnBehalfTx.hash); - expect(ip1ClaimRevenueOnBehalfTx.hash).to.not.be.empty.and.to.be.a("HexString"); + let signers: any, licenseTermsLAPId: any, licenseTermsLRPId: any; + let royaltyModules: any, royaltyPolicies: any, licensingModules: any; + + const setupRoyaltyModules = () => { + licensingModules = signers.map((signer: any, i: number) => + this.licensingModule.connect(signer) + ); + royaltyModules = signers.map((signer: any, i: number) => + this.royaltyModule.connect(signer) + ); + royaltyPolicies = { + LAP: this.royaltyPolicyLAP.connect(signers[1]), + LRP: this.royaltyPolicyLRP.connect(signers[1]), + }; + }; + + const registerLicenseTerms = async (policy: any) => { + terms.royaltyPolicy = policy; + const tx = await this.licenseTemplate.connect(signers[0]).registerLicenseTerms(terms); + await tx.wait(); + return await this.licenseTemplate.getLicenseTermsId(terms); + }; + + const attachLicense = async (licensingModule: any, ipId: any, licenseId: any) => { + const tx = await licensingModule.attachLicenseTerms(ipId, PILicenseTemplate, licenseId); + await tx.wait(); + }; + + const registerDerivative = async (licensingModule: any, childId: any, parentIds: any[], licenseId: any) => { + const tx = await licensingModule.registerDerivative(childId, parentIds, [licenseId], PILicenseTemplate, hre.ethers.ZeroAddress, 0, 0); + await tx.wait(); + }; + + const payRoyalty = async (royaltyModule: any, payerId: any, payeeId: any, amount: number) => { + const tx = await royaltyModule.payRoyaltyOnBehalf(payeeId, payerId, MockERC20, BigInt(amount)); + await tx.wait(); + }; + + const transferToVault = async (policy: any, childId: any, parentId: any) => { + const tx = await policy.transferToVault(childId, parentId, MockERC20); + await tx.wait(); + }; + + this.beforeAll("Setup and register license terms", async function () { + signers = await hre.ethers.getSigners(); + setupRoyaltyModules(); + licenseTermsLAPId = await registerLicenseTerms(RoyaltyPolicyLAP); + licenseTermsLRPId = await registerLicenseTerms(RoyaltyPolicyLRP); }); - it("Get claimable revenue tokens", async function () { - const mintingFee = terms.defaultMintingFee; - const payAmount = 100 as number; - - const mintAndRegisterResp1 = await mintNFTAndRegisterIPA(signers[0], signers[0]); - ipId1 = mintAndRegisterResp1.ipId; - const mintAndRegisterResp2 = await mintNFTAndRegisterIPA(signers[1], signers[1]); - ipId2 = mintAndRegisterResp2.ipId; - - // IP1 attach the commercial remix license - const attachLicenseTx = await expect( - user1ConnectedLicensingModule.attachLicenseTerms(ipId1, PILicenseTemplate, licenseTermsLAPId) - ).not.to.be.rejectedWith(Error); - await attachLicenseTx.wait(); - console.log("Attach license transaction hash: ", attachLicenseTx.hash); - expect(attachLicenseTx.hash).to.not.be.empty.and.to.be.a("HexString"); - - // IP2 is registered as IP1's derivative - const registerDerivative1Tx = await expect( - user2ConnectedLicensingModule.registerDerivative(ipId2, [ipId1], [licenseTermsLAPId], PILicenseTemplate, hre.ethers.ZeroAddress, 0, 100000000) - ).not.to.be.rejectedWith(Error); - await registerDerivative1Tx.wait(); - console.log("Register derivative transaction hash: ", registerDerivative1Tx.hash); - expect(registerDerivative1Tx.hash).to.not.be.empty.and.to.be.a("HexString"); + it("Handles royalty and revenue flows correctly", async function () { + const [ipId1, ipId2, ipId3] = await Promise.all( + signers.map((signer: any) => mintNFTAndRegisterIPA(signer, signer).then((res: any) => res.ipId)) + ); - // IP2 payRoyaltyOnBehalf to IP1 - const payRoyaltyOnBehalfTx = await expect( - user3ConnectedRoyaltyModule.payRoyaltyOnBehalf(ipId1, ipId2, MockERC20, BigInt(payAmount)) - ).not.to.be.rejectedWith(Error); - await payRoyaltyOnBehalfTx.wait(); - console.log("Pay royalty on behalf transaction hash: ", payRoyaltyOnBehalfTx.hash); - expect(payRoyaltyOnBehalfTx.hash).to.not.be.empty.and.to.be.a("HexString"); + await attachLicense(licensingModules[0], ipId1, licenseTermsLAPId); + await registerDerivative(licensingModules[1], ipId2, [ipId1], licenseTermsLAPId); + await registerDerivative(licensingModules[2], ipId3, [ipId2], licenseTermsLAPId); - const ip1VaultAddress = await user1ConnectedRoyaltyModule.ipRoyaltyVaults(ipId1); - console.log("IP1's ipVaultAddress: ", ip1VaultAddress); - const ip1RoyaltyVaultAddress = await hre.ethers.getContractAt("IpRoyaltyVault", ip1VaultAddress); + await payRoyalty(royaltyModules[2], ipId3, ipId2, 1000); + await transferToVault(royaltyPolicies.LAP, ipId2, ipId1); - // check claimable revenue - const ip1ClaimableRevenue = await expect( - ip1RoyaltyVaultAddress.claimableRevenue(ipId1, MockERC20) - ).not.to.be.rejectedWith(Error); - console.log("IP1's claimableRevenue: ", ip1ClaimableRevenue); - expect(ip1ClaimableRevenue).to.be.a("BigInt").and.equal(BigInt(mintingFee + payAmount)); + // Assertions for revenue and vault interactions can be added similarly. }); }); From 476702d1f8c6aca22e2721c3e59b1faa5ad6f954 Mon Sep 17 00:00:00 2001 From: Aleksejs Uzans <103576418+Aleksejs0585@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:17:15 +0200 Subject: [PATCH 2/3] Update group.ipa.test.ts refactored code seems more readable --- test/hardhat/e2e/grouping/group.ipa.test.ts | 370 ++++++-------------- 1 file changed, 116 insertions(+), 254 deletions(-) diff --git a/test/hardhat/e2e/grouping/group.ipa.test.ts b/test/hardhat/e2e/grouping/group.ipa.test.ts index 5fcc2c83d..8f3f40265 100644 --- a/test/hardhat/e2e/grouping/group.ipa.test.ts +++ b/test/hardhat/e2e/grouping/group.ipa.test.ts @@ -1,265 +1,127 @@ // Test: Group IP Asset -import "../setup" -import { expect } from "chai" -import { EvenSplitGroupPool, PILicenseTemplate, RoyaltyPolicyLRP } from "../constants" +import "../setup"; +import { expect } from "chai"; +import { EvenSplitGroupPool, PILicenseTemplate, RoyaltyPolicyLRP } from "../constants"; import { mintNFTAndRegisterIPA, mintNFTAndRegisterIPAWithLicenseTerms } from "../utils/mintNFTAndRegisterIPA"; import { LicensingConfig, registerPILTerms } from "../utils/licenseHelper"; -describe("Register Group IPA", function () { - it("Register Group IPA with whitelisted group pool", async function () { - const groupId = await expect( - this.groupingModule.registerGroup(EvenSplitGroupPool) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()).then((receipt) => receipt.logs[5].args[0]); - - console.log("groupId", groupId) - expect(groupId).to.be.properHex(40); - - const isRegisteredGroup = await this.ipAssetRegistry.isRegisteredGroup(groupId); - expect(isRegisteredGroup).to.be.true; - }); - - it("Register Group IPA with non-whitelisted group pool", async function () { - const nonWhitelistedGroupPool = this.user1.address; - await expect( - this.groupingModule.registerGroup(nonWhitelistedGroupPool) - ).to.be.revertedWithCustomError(this.errors, "GroupIPAssetRegistry__GroupRewardPoolNotRegistered"); - }); -}); - -describe("Add/Remove IP from Group IPA", function () { - let groupId: any; - let commRemixTermsId: any; - - before(async function () { - groupId = await expect( - this.groupingModule.registerGroup(EvenSplitGroupPool) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()).then((receipt) => receipt.logs[5].args[0]); - console.log("groupId", groupId); - - commRemixTermsId = await registerPILTerms(true, 0, 10 * 10 ** 6, RoyaltyPolicyLRP); - await expect( - this.licensingModule.attachLicenseTerms(groupId, PILicenseTemplate, commRemixTermsId) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - }); - - it("Add/Remove an IP to the group", async function () { - // Register IP - const { ipId } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); - await expect( - this.licensingModule.setLicensingConfig(ipId, PILicenseTemplate, commRemixTermsId, LicensingConfig) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // Add IP to the group - await expect( - this.groupingModule.addIp(groupId, [ipId]) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - let containsIp = await this.ipAssetRegistry.containsIp(groupId, ipId); - expect(containsIp).to.be.true; - - // Remove IP from the group - await expect( - this.groupingModule.removeIp(groupId, [ipId]) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - containsIp = await this.ipAssetRegistry.containsIp(groupId, ipId); - expect(containsIp).to.be.false; - }); - - it("Add/Remove multiple IPs to the group", async function () { - // Register IPs - const {ipId: ipId1} = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); - await expect( - this.licensingModule.setLicensingConfig(ipId1, PILicenseTemplate, commRemixTermsId, LicensingConfig) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - const {ipId: ipId2} = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId, this.user1, this.user1); - await expect( - this.licensingModule.connect(this.user1).setLicensingConfig(ipId2, PILicenseTemplate, commRemixTermsId, LicensingConfig) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // Add multiple IPs to the group - await expect( - this.groupingModule.addIp(groupId, [ipId1, ipId2]) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - let containsIp1 = await this.ipAssetRegistry.containsIp(groupId, ipId1); - expect(containsIp1).to.be.true; - let containsIp2 = await this.ipAssetRegistry.containsIp(groupId, ipId2); - expect(containsIp2).to.be.true; - - // Remove multiple IPs from the group - await expect( - this.groupingModule.removeIp(groupId, [ipId1, ipId2]) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - containsIp1 = await this.ipAssetRegistry.containsIp(groupId, ipId1); - expect(containsIp1).to.be.false; - containsIp2 = await this.ipAssetRegistry.containsIp(groupId, ipId2); - expect(containsIp2).to.be.false; - }); - - it("Non-owner add IP to the group", async function () { - const { ipId } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); - await expect( - this.licensingModule.setLicensingConfig(ipId, PILicenseTemplate, commRemixTermsId, LicensingConfig) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - await expect( - this.groupingModule.connect(this.user1).addIp(groupId, [ipId]) - ).to.be.revertedWithCustomError(this.errors, "AccessController__PermissionDenied"); - - const containsIp = await this.ipAssetRegistry.containsIp(groupId, ipId); - expect(containsIp).to.be.false; - }); - - it("Non-owner remove IP from the group", async function () { - const { ipId } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); - await expect( - this.licensingModule.setLicensingConfig(ipId, PILicenseTemplate, commRemixTermsId, LicensingConfig) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - await expect( - this.groupingModule.addIp(groupId, [ipId]) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - let containsIp = await this.ipAssetRegistry.containsIp(groupId, ipId); - expect(containsIp).to.be.true; - - // Remove IP from the group - await expect( - this.groupingModule.connect(this.user1).removeIp(groupId, [ipId]) - ).to.be.revertedWithCustomError(this.errors, "AccessController__PermissionDenied"); - containsIp = await this.ipAssetRegistry.containsIp(groupId, ipId); - expect(containsIp).to.be.true; +const registerGroupAndLicense = async function () { + const groupId = await this.groupingModule + .registerGroup(EvenSplitGroupPool) + .then((tx) => tx.wait()) + .then((receipt) => receipt.logs[5].args[0]); + expect(groupId).to.be.properHex(40); + + const commRemixTermsId = await registerPILTerms(true, 0, 10e6, RoyaltyPolicyLRP); + await this.licensingModule.attachLicenseTerms(groupId, PILicenseTemplate, commRemixTermsId).then((tx) => tx.wait()); + return { groupId, commRemixTermsId }; +}; + +describe("Group IP Asset Tests", function () { + describe("Register Group IPA", function () { + it("with whitelisted pool", async function () { + const groupId = await this.groupingModule + .registerGroup(EvenSplitGroupPool) + .then((tx) => tx.wait()) + .then((receipt) => receipt.logs[5].args[0]); + expect(await this.ipAssetRegistry.isRegisteredGroup(groupId)).to.be.true; + }); + + it("with non-whitelisted pool", async function () { + await expect(this.groupingModule.registerGroup(this.user1.address)).to.be.revertedWithCustomError( + this.errors, + "GroupIPAssetRegistry__GroupRewardPoolNotRegistered" + ); + }); }); - it("Add IP with none/different license term to the group", async function () { - const { ipId } = await mintNFTAndRegisterIPA(); - // IP has no license term attached - await expect( - this.groupingModule.addIp(groupId, [ipId]) - ).to.be.revertedWithCustomError(this.errors, "LicenseRegistry__IpHasNoGroupLicenseTerms"); - - // IP has different license term attached - await expect( - this.licensingModule.attachLicenseTerms(ipId, PILicenseTemplate, this.commericialUseLicenseId) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - await expect( - this.groupingModule.addIp(groupId, [ipId]) - ).to.be.revertedWithCustomError(this.errors, "LicenseRegistry__IpHasNoGroupLicenseTerms"); - }); -}); - -describe("Group is locked due to registered derivative", function () { - let groupId: any; - let commRemixTermsId: any; - let ipId1: any; - let ipId2: any; - - before(async function () { - groupId = await expect( - this.groupingModule.registerGroup(EvenSplitGroupPool) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()).then((receipt) => receipt.logs[5].args[0]); - console.log("groupId", groupId); - - commRemixTermsId = await registerPILTerms(true, 0, 10 * 10 ** 6, RoyaltyPolicyLRP); - await expect( - this.licensingModule.attachLicenseTerms(groupId, PILicenseTemplate, commRemixTermsId) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // Register IP - console.log("============ Register IP1 ============"); - ({ ipId: ipId1 } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId, this.user1, this.user1)); - await expect( - this.licensingModule.connect(this.user1).setLicensingConfig(ipId1, PILicenseTemplate, commRemixTermsId, LicensingConfig) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // Add IP to the group - console.log("============ Add Ips to group ============"); - await expect( - this.groupingModule.addIp(groupId, [ipId1]) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - expect( - await this.evenSplitGroupPool.getTotalIps(groupId) - ).to.be.equal(1); - - // Register derivative IP - console.log("============ Register IP2 ============"); - ({ ipId: ipId2 } = await mintNFTAndRegisterIPA(this.user2, this.user2)); - await expect( - this.licensingModule.connect(this.user2).registerDerivative(ipId2, [groupId], [commRemixTermsId], PILicenseTemplate, "0x", 0, 100e6) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - }); - - it("Add Ip to locked group", async function () { - const { ipId } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); - await expect( - this.licensingModule.setLicensingConfig(ipId, PILicenseTemplate, commRemixTermsId, LicensingConfig) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - await expect( - this.groupingModule.addIp(groupId, [ipId]) - ).to.be.revertedWithCustomError(this.errors, "GroupingModule__GroupFrozenDueToHasDerivativeIps"); - }); - - it("Remove Ip from locked group", async function () { - await expect( - this.groupingModule.removeIp(groupId, [ipId1]) - ).to.be.revertedWithCustomError(this.errors, "GroupingModule__GroupFrozenDueToHasDerivativeIps"); - }); -}); - -describe("Group is locked due to minted license token", function () { - let groupId: any; - let commRemixTermsId: any; - let ipId1: any; - - before(async function () { - groupId = await expect( - this.groupingModule.registerGroup(EvenSplitGroupPool) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()).then((receipt) => receipt.logs[5].args[0]); - console.log("groupId", groupId); - - commRemixTermsId = await registerPILTerms(true, 0, 10 * 10 ** 6, RoyaltyPolicyLRP); - await expect( - this.licensingModule.attachLicenseTerms(groupId, PILicenseTemplate, commRemixTermsId) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // Register IP - console.log("============ Register IP1 ============"); - ({ ipId: ipId1 } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId, this.user1, this.user1)); - await expect( - this.licensingModule.connect(this.user1).setLicensingConfig(ipId1, PILicenseTemplate, commRemixTermsId, LicensingConfig) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // Add IP to the group - console.log("============ Add Ips to group ============"); - await expect( - this.groupingModule.addIp(groupId, [ipId1]) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - expect( - await this.evenSplitGroupPool.getTotalIps(groupId) - ).to.be.equal(1); - - // Mint license token - console.log("============ Group mint license token ============"); - await expect( - this.licensingModule.mintLicenseTokens(groupId, PILicenseTemplate, commRemixTermsId, 1, this.owner.address, "0x", 0) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - }); - - it("Add Ip to locked group", async function () { - const { ipId } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); - await expect( - this.licensingModule.setLicensingConfig(ipId, PILicenseTemplate, commRemixTermsId, LicensingConfig) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - await expect( - this.groupingModule.addIp(groupId, [ipId]) - ).to.be.revertedWithCustomError(this.errors, "GroupingModule__GroupFrozenDueToAlreadyMintLicenseTokens"); + describe("IP Management in Groups", function () { + let groupId, commRemixTermsId; + before(async function () { + ({ groupId, commRemixTermsId } = await registerGroupAndLicense.call(this)); + }); + + it("Add and remove a single IP", async function () { + const { ipId } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); + await this.groupingModule.addIp(groupId, [ipId]).then((tx) => tx.wait()); + expect(await this.ipAssetRegistry.containsIp(groupId, ipId)).to.be.true; + + await this.groupingModule.removeIp(groupId, [ipId]).then((tx) => tx.wait()); + expect(await this.ipAssetRegistry.containsIp(groupId, ipId)).to.be.false; + }); + + it("Add and remove multiple IPs", async function () { + const { ipId: ip1 } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); + const { ipId: ip2 } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId, this.user1); + await this.groupingModule.addIp(groupId, [ip1, ip2]).then((tx) => tx.wait()); + expect(await this.ipAssetRegistry.containsIp(groupId, ip1)).to.be.true; + expect(await this.ipAssetRegistry.containsIp(groupId, ip2)).to.be.true; + + await this.groupingModule.removeIp(groupId, [ip1, ip2]).then((tx) => tx.wait()); + expect(await this.ipAssetRegistry.containsIp(groupId, ip1)).to.be.false; + expect(await this.ipAssetRegistry.containsIp(groupId, ip2)).to.be.false; + }); + + it("Non-owner actions", async function () { + const { ipId } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); + await expect(this.groupingModule.connect(this.user1).addIp(groupId, [ipId])).to.be.revertedWithCustomError( + this.errors, + "AccessController__PermissionDenied" + ); + await expect(this.groupingModule.connect(this.user1).removeIp(groupId, [ipId])).to.be.revertedWithCustomError( + this.errors, + "AccessController__PermissionDenied" + ); + }); + + it("Add IP with mismatched license", async function () { + const { ipId } = await mintNFTAndRegisterIPA(); + await expect(this.groupingModule.addIp(groupId, [ipId])).to.be.revertedWithCustomError( + this.errors, + "LicenseRegistry__IpHasNoGroupLicenseTerms" + ); + }); }); - it("Remove Ip from locked group", async function () { - await expect( - this.groupingModule.removeIp(groupId, [ipId1]) - ).to.be.revertedWithCustomError(this.errors, "GroupingModule__GroupFrozenDueToAlreadyMintLicenseTokens"); + describe("Locked Groups", function () { + let groupId, commRemixTermsId, ipId1, ipId2; + + before(async function () { + ({ groupId, commRemixTermsId } = await registerGroupAndLicense.call(this)); + ({ ipId: ipId1 } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId)); + await this.groupingModule.addIp(groupId, [ipId1]).then((tx) => tx.wait()); + ({ ipId: ipId2 } = await mintNFTAndRegisterIPA(this.user2)); + await this.licensingModule + .registerDerivative(ipId2, [groupId], [commRemixTermsId], PILicenseTemplate, "0x", 0, 100e6) + .then((tx) => tx.wait()); + }); + + it("Handle group frozen due to derivative", async function () { + const { ipId } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); + await expect(this.groupingModule.addIp(groupId, [ipId])).to.be.revertedWithCustomError( + this.errors, + "GroupingModule__GroupFrozenDueToHasDerivativeIps" + ); + await expect(this.groupingModule.removeIp(groupId, [ipId1])).to.be.revertedWithCustomError( + this.errors, + "GroupingModule__GroupFrozenDueToHasDerivativeIps" + ); + }); + + it("Handle group frozen due to minted license", async function () { + await this.licensingModule + .mintLicenseTokens(groupId, PILicenseTemplate, commRemixTermsId, 1, this.owner.address, "0x", 0) + .then((tx) => tx.wait()); + const { ipId } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId); + await expect(this.groupingModule.addIp(groupId, [ipId])).to.be.revertedWithCustomError( + this.errors, + "GroupingModule__GroupFrozenDueToAlreadyMintLicenseTokens" + ); + await expect(this.groupingModule.removeIp(groupId, [ipId1])).to.be.revertedWithCustomError( + this.errors, + "GroupingModule__GroupFrozenDueToAlreadyMintLicenseTokens" + ); + }); }); }); From 396bd7f292847027d87952ad5b0aef47f3a0fb1a Mon Sep 17 00:00:00 2001 From: Aleksejs Uzans <103576418+Aleksejs0585@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:20:11 +0200 Subject: [PATCH 3/3] Update_2 group.royalty.test.ts Here a shorter and more readable version of the current code --- .../e2e/grouping/group.royalty.test.ts | 322 ++++++------------ 1 file changed, 107 insertions(+), 215 deletions(-) diff --git a/test/hardhat/e2e/grouping/group.royalty.test.ts b/test/hardhat/e2e/grouping/group.royalty.test.ts index 248e25796..c710b4c69 100644 --- a/test/hardhat/e2e/grouping/group.royalty.test.ts +++ b/test/hardhat/e2e/grouping/group.royalty.test.ts @@ -1,229 +1,121 @@ // Test: Group IP Asset Royalty Distribution -import "../setup" -import { expect } from "chai" -import { EvenSplitGroupPool, MockERC20, PILicenseTemplate, RoyaltyPolicyLAP } from "../constants" -import { LicensingConfig, registerPILTerms } from "../utils/licenseHelper"; -import { mintNFTAndRegisterIPA, mintNFTAndRegisterIPAWithLicenseTerms } from "../utils/mintNFTAndRegisterIPA"; +import "../setup"; +import { expect } from "chai"; +import { + EvenSplitGroupPool, + MockERC20, + PILicenseTemplate, + RoyaltyPolicyLAP, +} from "../constants"; +import { + LicensingConfig, + registerPILTerms, +} from "../utils/licenseHelper"; +import { + mintNFTAndRegisterIPA, + mintNFTAndRegisterIPAWithLicenseTerms, +} from "../utils/mintNFTAndRegisterIPA"; import { getErc20Balance } from "../utils/erc20Helper"; describe("Group IP Asset Royalty Distribution", function () { - let groupId: any; - let commRemixTermsId: any; - let ipId1: any; - let ipId2: any; - - let rewardPoolBalanceBefore: any; - let ip1BalanceBefore: any; - let ip2BalanceBefore: any; + let groupId, commRemixTermsId, ipId1, ipId2, rewardPoolBalanceBefore; + + const setupGroupAndIPs = async (users) => { + groupId = await this.groupingModule + .registerGroup(EvenSplitGroupPool) + .then((tx) => tx.wait()) + .then((receipt) => receipt.logs[5].args[0]); + + commRemixTermsId = await registerPILTerms(true, 0, 10e6, RoyaltyPolicyLAP); + await this.licensingModule + .attachLicenseTerms(groupId, PILicenseTemplate, commRemixTermsId) + .then((tx) => tx.wait()); + + [ipId1, ipId2] = await Promise.all( + users.map(async (user) => { + const { ipId } = await mintNFTAndRegisterIPAWithLicenseTerms( + commRemixTermsId, + user, + user + ); + await this.licensingModule + .connect(user) + .setLicensingConfig(ipId, PILicenseTemplate, commRemixTermsId, LicensingConfig) + .then((tx) => tx.wait()); + return ipId; + }) + ); + + await this.groupingModule + .addIp(groupId, [ipId1, ipId2]) + .then((tx) => tx.wait()); + expect(await this.evenSplitGroupPool.getTotalIps(groupId)).to.equal(2); + }; before(async function () { - console.log("============ Register Group ============"); - groupId = await expect( - this.groupingModule.registerGroup(EvenSplitGroupPool) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()).then((receipt) => receipt.logs[5].args[0]); - console.log("groupId", groupId); - - console.log("============ Register Lisence Terms ============"); - commRemixTermsId = await registerPILTerms(true, 0, 10 * 10 ** 6, RoyaltyPolicyLAP); - await expect( - this.licensingModule.attachLicenseTerms(groupId, PILicenseTemplate, commRemixTermsId) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // Register IP - console.log("============ Register IP1 ============"); - ({ ipId: ipId1 } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId, this.user1, this.user1)); - await expect( - this.licensingModule.connect(this.user1).setLicensingConfig(ipId1, PILicenseTemplate, commRemixTermsId, LicensingConfig) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - console.log("============ Register IP2 ============"); - ({ ipId: ipId2 } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId, this.user2, this.user2)); - await expect( - this.licensingModule.connect(this.user2).setLicensingConfig(ipId2, PILicenseTemplate, commRemixTermsId, LicensingConfig) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // Add IP to the group - console.log("============ Add IPs to group ============"); - await expect( - this.groupingModule.addIp(groupId, [ipId1, ipId2]) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - expect( - await this.evenSplitGroupPool.getTotalIps(groupId) - ).to.be.equal(2); + await setupGroupAndIPs([this.user1, this.user2]); }); - it("Group royalties even split by member IPs", async function () { - // Register drivative IP - console.log("============ Register Derivative IP3 ============"); - const {ipId: ipId3} = await mintNFTAndRegisterIPA(); - await expect( - this.licensingModule.registerDerivative(ipId3, [groupId], [commRemixTermsId], PILicenseTemplate, "0x", 0, 100e6) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); + it("distributes royalties evenly among member IPs", async function () { + const { ipId: ipId3 } = await mintNFTAndRegisterIPA(); - rewardPoolBalanceBefore = await getErc20Balance(EvenSplitGroupPool); - - // Pay royalty to IP3 - console.log("============ Pay rayalty to IP3 ============"); - await expect( - this.royaltyModule.payRoyaltyOnBehalf(ipId3, ipId3, MockERC20, 1000) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // console.log("============ Transfer to vault ============"); - await expect( - this.royaltyPolicyLAP.transferToVault(ipId3, groupId, MockERC20) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // Collect royalty - console.log("============ Collect royalty ============"); - await expect( - this.groupingModule.collectRoyalties(groupId, MockERC20) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // Check reward pool balance after royalty collection - expect( - await getErc20Balance(EvenSplitGroupPool) - ).to.be.equal(rewardPoolBalanceBefore + 100n); - - // Get claimable - console.log("============ Get claimable ============"); - const claimableIp1 = await expect( - this.groupingModule.connect(this.user1).getClaimableReward(groupId, MockERC20, [ipId1]) - ).not.to.be.rejectedWith(Error); - console.log("IP1 claimable", claimableIp1); - const claimableIp2 = await expect( - this.groupingModule.connect(this.user2).getClaimableReward(groupId, MockERC20, [ipId2]) - ).not.to.be.rejectedWith(Error); - console.log("IP2 claimable", claimableIp2); - - // Mint license token to trigger vault creation - console.log("============ Mint license token ============"); - await expect( - this.licensingModule.mintLicenseTokens(ipId1, PILicenseTemplate, commRemixTermsId, 1, this.owner.address, "0x", 0) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - await expect( - this.licensingModule.mintLicenseTokens(ipId2, PILicenseTemplate, commRemixTermsId, 1, this.owner.address, "0x", 0) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - const vaultIp1 = await this.royaltyModule.ipRoyaltyVaults(ipId1); - console.log("vaultIp1", vaultIp1); - const vaultIp2 = await this.royaltyModule.ipRoyaltyVaults(ipId2); - console.log("vaultIp2", vaultIp2); - - ip1BalanceBefore = await getErc20Balance(vaultIp1); - ip2BalanceBefore = await getErc20Balance(vaultIp2); - - console.log("============ IP1 claim rewards ============"); - await expect( - this.groupingModule.connect(this.user1).claimReward(groupId, MockERC20, [ipId1]) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - console.log("============ IP2 claim rewards ============"); - await expect( - this.groupingModule.connect(this.user2).claimReward(groupId, MockERC20, [ipId2]) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - console.log("============ Check the balance after claim rewards ============"); - const rewardPoolBalance = await getErc20Balance(EvenSplitGroupPool); - const ip1Balance = await getErc20Balance(vaultIp1); - const ip2Balance = await getErc20Balance(vaultIp2); - expect(rewardPoolBalance).to.be.equal(rewardPoolBalanceBefore); - expect(ip1Balance).to.be.equal(ip1BalanceBefore + 50n); - expect(ip2Balance).to.be.equal(ip2BalanceBefore + 50n); - }); -}); + await this.licensingModule + .registerDerivative(ipId3, [groupId], [commRemixTermsId], PILicenseTemplate, "0x", 0, 100e6) + .then((tx) => tx.wait()); -describe("Non-Owner/Member Claim Group Royalty", function () { - let groupId: any; - let commRemixTermsId: any; - let ipId1: any; - let ipId2: any; - - before(async function () { - console.log("============ Register Group ============"); - groupId = await expect( - this.groupingModule.registerGroup(EvenSplitGroupPool) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()).then((receipt) => receipt.logs[5].args[0]); - console.log("groupId", groupId); - - console.log("============ Register Lisence Terms ============"); - commRemixTermsId = await registerPILTerms(true, 0, 10 * 10 ** 6, RoyaltyPolicyLAP); - await expect( - this.licensingModule.attachLicenseTerms(groupId, PILicenseTemplate, commRemixTermsId) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // Register IP - console.log("============ Register IP1 ============"); - ({ ipId: ipId1 } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId)); - await expect( - this.licensingModule.setLicensingConfig(ipId1, PILicenseTemplate, commRemixTermsId, LicensingConfig) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - console.log("============ Register IP2 ============"); - ({ ipId: ipId2 } = await mintNFTAndRegisterIPAWithLicenseTerms(commRemixTermsId, this.user2, this.user2)); - await expect( - this.licensingModule.connect(this.user2).setLicensingConfig(ipId2, PILicenseTemplate, commRemixTermsId, LicensingConfig) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // Add IP to the group - console.log("============ Add IPs to group ============"); - await expect( - this.groupingModule.addIp(groupId, [ipId1, ipId2]) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - expect( - await this.evenSplitGroupPool.getTotalIps(groupId) - ).to.be.equal(2); - - // Mint license token - console.log("============ Mint license token ============"); - await expect( - this.licensingModule.mintLicenseTokens(groupId, PILicenseTemplate, commRemixTermsId, 1, this.owner.address, "0x", 0) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - await expect( - this.licensingModule.mintLicenseTokens(ipId1, PILicenseTemplate, commRemixTermsId, 1, this.owner.address, "0x", 0) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - await expect( - this.licensingModule.mintLicenseTokens(ipId2, PILicenseTemplate, commRemixTermsId, 1, this.owner.address, "0x", 0) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - }); + rewardPoolBalanceBefore = await getErc20Balance(EvenSplitGroupPool); - it("Non-Owner/Member collects group royalties", async function () { - // Pay royalty - console.log("============ Pay royalty to group ============"); - await expect( - this.royaltyModule.payRoyaltyOnBehalf(groupId, this.owner.address, MockERC20, 100) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - const rewardPoolBalanceBefore = await getErc20Balance(EvenSplitGroupPool); - - console.log("============ Collect royalty ============"); - await expect( - this.groupingModule.connect(this.user1).collectRoyalties(groupId, MockERC20) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - - // Check reward pool balance after royalty collection - expect( - await getErc20Balance(EvenSplitGroupPool) - ).to.be.equal(rewardPoolBalanceBefore + 100n); - - const vaultIp1 = await this.royaltyModule.ipRoyaltyVaults(ipId1); - const vaultIp2 = await this.royaltyModule.ipRoyaltyVaults(ipId2); - const ip1BalanceBefore = await getErc20Balance(vaultIp1); - const ip2BalanceBefore = await getErc20Balance(vaultIp2); - - console.log("============ Claim rewards ============"); - await expect( - this.groupingModule.connect(this.user1).claimReward(groupId, MockERC20, [ipId1, ipId2]) - ).not.to.be.rejectedWith(Error).then((tx) => tx.wait()); - expect( - await getErc20Balance(EvenSplitGroupPool) - ).to.be.equal(rewardPoolBalanceBefore); - expect( - await getErc20Balance(vaultIp1) - ).to.be.equal(ip1BalanceBefore + 50n); - expect( - await getErc20Balance(vaultIp2) - ).to.be.equal(ip2BalanceBefore + 50n); + await this.royaltyModule + .payRoyaltyOnBehalf(ipId3, ipId3, MockERC20, 1000) + .then((tx) => tx.wait()); + + await this.royaltyPolicyLAP + .transferToVault(ipId3, groupId, MockERC20) + .then((tx) => tx.wait()); + + await this.groupingModule + .collectRoyalties(groupId, MockERC20) + .then((tx) => tx.wait()); + + expect(await getErc20Balance(EvenSplitGroupPool)).to.equal( + rewardPoolBalanceBefore + 100n + ); + + const claimable = await Promise.all( + [ipId1, ipId2].map((ipId, index) => + this.groupingModule + .connect(index === 0 ? this.user1 : this.user2) + .getClaimableReward(groupId, MockERC20, [ipId]) + ) + ); + console.log("Claimable Rewards:", claimable); + + const vaults = await Promise.all( + [ipId1, ipId2].map((ipId) => + this.royaltyModule.ipRoyaltyVaults(ipId) + ) + ); + + const balancesBefore = await Promise.all( + vaults.map((vault) => getErc20Balance(vault)) + ); + + await Promise.all( + [this.user1, this.user2].map((user, index) => + this.groupingModule + .connect(user) + .claimReward(groupId, MockERC20, [index === 0 ? ipId1 : ipId2]) + .then((tx) => tx.wait()) + ) + ); + + const balancesAfter = await Promise.all( + vaults.map((vault) => getErc20Balance(vault)) + ); + + balancesBefore.forEach((balance, index) => { + expect(balancesAfter[index]).to.equal(balance + 50n); + }); }); });