From 73bcb0f207340a046307cf095f2946aeb18d67cb Mon Sep 17 00:00:00 2001 From: Kingter <83567446+kingster-will@users.noreply.github.com> Date: Thu, 17 Oct 2024 12:54:31 -0700 Subject: [PATCH] Introduce maxMintingFee when minting licensing (#276) --- .../modules/licensing/ILicensingModule.sol | 8 +- contracts/lib/Errors.sol | 3 + .../modules/licensing/LicensingModule.sol | 92 ++++-- .../big-bang/SingleNftCollection.t.sol | 18 +- .../integration/flows/disputes/Disputes.t.sol | 18 +- .../integration/flows/grouping/Grouping.t.sol | 6 +- .../licensing/LicensingIntegration.t.sol | 15 +- .../flows/licensing/LicensingScenarios.t.sol | 9 +- .../integration/flows/royalty/Royalty.t.sol | 12 +- test/foundry/invariants/DisputeModule.t.sol | 3 +- test/foundry/invariants/LicensingModule.t.sol | 5 +- .../modules/dispute/DisputeModule.t.sol | 3 +- .../modules/grouping/EvenSplitGroupPool.t.sol | 2 +- .../modules/grouping/GroupingModule.t.sol | 10 +- .../modules/licensing/LicensingModule.t.sol | 282 ++++++++++++++---- .../modules/licensing/PILicenseTemplate.t.sol | 6 +- test/foundry/registries/LicenseRegistry.t.sol | 6 +- 17 files changed, 385 insertions(+), 113 deletions(-) diff --git a/contracts/interfaces/modules/licensing/ILicensingModule.sol b/contracts/interfaces/modules/licensing/ILicensingModule.sol index 29411dbf9..b87dc4164 100644 --- a/contracts/interfaces/modules/licensing/ILicensingModule.sol +++ b/contracts/interfaces/modules/licensing/ILicensingModule.sol @@ -82,6 +82,7 @@ interface ILicensingModule is IModule { /// @param amount The amount of license tokens to mint. /// @param receiver The address of the receiver. /// @param royaltyContext The context of the royalty. + /// @param maxMintingFee The maximum minting fee that the caller is willing to pay. if set to 0 then no limit. /// @return startLicenseTokenId The start ID of the minted license tokens. function mintLicenseTokens( address licensorIpId, @@ -89,7 +90,8 @@ interface ILicensingModule is IModule { uint256 licenseTermsId, uint256 amount, address receiver, - bytes calldata royaltyContext + bytes calldata royaltyContext, + uint256 maxMintingFee ) external returns (uint256 startLicenseTokenId); /// @notice Registers a derivative directly with parent IP's license terms, without needing license tokens, @@ -102,12 +104,14 @@ interface ILicensingModule is IModule { /// @param licenseTermsIds The IDs of the license terms that the parent IP supports. /// @param licenseTemplate The address of the license template of the license terms Ids. /// @param royaltyContext The context of the royalty. + /// @param maxMintingFee The maximum minting fee that the caller is willing to pay. if set to 0 then no limit. function registerDerivative( address childIpId, address[] calldata parentIpIds, uint256[] calldata licenseTermsIds, address licenseTemplate, - bytes calldata royaltyContext + bytes calldata royaltyContext, + uint256 maxMintingFee ) external; /// @notice Registers a derivative with license tokens. diff --git a/contracts/lib/Errors.sol b/contracts/lib/Errors.sol index d8311ad9b..0e44fd97f 100644 --- a/contracts/lib/Errors.sol +++ b/contracts/lib/Errors.sol @@ -365,6 +365,9 @@ library Errors { /// @notice Grouping Module is zero address. error LicensingModule__ZeroGroupingModule(); + /// @notice licensing minting fee is above the maximum minting fee. + error LicensingModule__MintingFeeExceedMaxMintingFee(uint256 mintingFee, uint256 maxMintingFee); + //////////////////////////////////////////////////////////////////////////// // Dispute Module // //////////////////////////////////////////////////////////////////////////// diff --git a/contracts/modules/licensing/LicensingModule.sol b/contracts/modules/licensing/LicensingModule.sol index 014ee5c97..e74dbb9a7 100644 --- a/contracts/modules/licensing/LicensingModule.sol +++ b/contracts/modules/licensing/LicensingModule.sol @@ -48,6 +48,13 @@ contract LicensingModule is using Strings for *; using IPAccountStorageOps for IIPAccount; + struct RoyaltyPolicyInfo { + address royaltyPolicy; + uint32 royaltyPercent; + uint256 mintingFeeByLicense; + address currencyToken; + } + /// @inheritdoc IModule string public constant override name = LICENSING_MODULE_KEY; @@ -148,6 +155,7 @@ contract LicensingModule is /// @param amount The amount of license tokens to mint. /// @param receiver The address of the receiver. /// @param royaltyContext The context of the royalty. + /// @param maxMintingFee The maximum minting fee that the caller is willing to pay. if set to 0 then no limit. /// @return startLicenseTokenId The start ID of the minted license tokens. function mintLicenseTokens( address licensorIpId, @@ -155,7 +163,8 @@ contract LicensingModule is uint256 licenseTermsId, uint256 amount, address receiver, - bytes calldata royaltyContext + bytes calldata royaltyContext, + uint256 maxMintingFee ) external whenNotPaused nonReentrant returns (uint256 startLicenseTokenId) { if (amount == 0) { revert Errors.LicensingModule__MintAmountZero(); @@ -186,7 +195,16 @@ contract LicensingModule is ); } - _payMintingFee(licensorIpId, licenseTemplate, licenseTermsId, amount, royaltyContext, lsc, mintingFeeByHook); + _payMintingFee( + licensorIpId, + licenseTemplate, + licenseTermsId, + amount, + royaltyContext, + lsc, + mintingFeeByHook, + maxMintingFee + ); if (!ILicenseTemplate(licenseTemplate).verifyMintLicenseToken(licenseTermsId, receiver, licensorIpId, amount)) { revert Errors.LicensingModule__LicenseDenyMintLicenseToken(licenseTemplate, licenseTermsId, licensorIpId); @@ -223,12 +241,14 @@ contract LicensingModule is /// @param licenseTermsIds The IDs of the license terms that the parent IP supports. /// @param licenseTemplate The address of the license template of the license terms Ids. /// @param royaltyContext The context of the royalty. + /// @param maxMintingFee The maximum minting fee that the caller is willing to pay. if set to 0 then no limit. function registerDerivative( address childIpId, address[] calldata parentIpIds, uint256[] calldata licenseTermsIds, address licenseTemplate, - bytes calldata royaltyContext + bytes calldata royaltyContext, + uint256 maxMintingFee ) external whenNotPaused nonReentrant verifyPermission(childIpId) { if (parentIpIds.length != licenseTermsIds.length) { revert Errors.LicensingModule__LicenseTermsLengthMismatch(parentIpIds.length, licenseTermsIds.length); @@ -243,8 +263,14 @@ contract LicensingModule is // All license terms must be compatible with each other. // Verify that the derivative IP is permitted under all license terms from the parent IPs. address childIpOwner = IIPAccount(payable(childIpId)).owner(); - ILicenseTemplate lct = ILicenseTemplate(licenseTemplate); - if (!lct.verifyRegisterDerivativeForAllParents(childIpId, parentIpIds, licenseTermsIds, childIpOwner)) { + if ( + !ILicenseTemplate(licenseTemplate).verifyRegisterDerivativeForAllParents( + childIpId, + parentIpIds, + licenseTermsIds, + childIpOwner + ) + ) { revert Errors.LicensingModule__LicenseNotCompatibleForDerivative(childIpId); } @@ -266,7 +292,8 @@ contract LicensingModule is licenseTermsIds, licenseTemplate, childIpOwner, - royaltyContext + royaltyContext, + maxMintingFee ); // emit event emit DerivativeRegistered( @@ -475,7 +502,8 @@ contract LicensingModule is uint256[] calldata licenseTermsIds, address licenseTemplate, address childIpOwner, - bytes calldata royaltyContext + bytes calldata royaltyContext, + uint256 maxMintingFee ) private returns (address[] memory royaltyPolicies, uint32[] memory royaltyPercents) { royaltyPolicies = new address[](licenseTermsIds.length); royaltyPercents = new uint32[](licenseTermsIds.length); @@ -487,7 +515,8 @@ contract LicensingModule is licenseTemplate, licenseTermsIds[i], childIpOwner, - royaltyContext + royaltyContext, + maxMintingFee ); royaltyPolicies[i] = royaltyPolicy; royaltyPercents[i] = royaltyPercent; @@ -500,7 +529,8 @@ contract LicensingModule is address licenseTemplate, uint256 licenseTermsId, address childIpOwner, - bytes calldata royaltyContext + bytes calldata royaltyContext, + uint256 maxMintingFee ) private returns (address royaltyPolicy, uint32 royaltyPercent) { Licensing.LicensingConfig memory lsc = LICENSE_REGISTRY.getLicensingConfig( parentIpId, @@ -526,7 +556,8 @@ contract LicensingModule is 1, royaltyContext, lsc, - mintingFeeByHook + mintingFeeByHook, + maxMintingFee ); } @@ -540,6 +571,8 @@ contract LicensingModule is /// @param amount The amount of license tokens to mint. /// @param royaltyContext The context of the royalty. /// @param licensingConfig The minting license config + /// @param mintingFeeByHook The minting fee set by the hook. + /// @param maxMintingFee The maximum minting fee that the caller is willing to pay. /// @return royaltyPolicy The address of the royalty policy. /// @return royaltyPercent The license royalty percentage function _payMintingFee( @@ -549,26 +582,51 @@ contract LicensingModule is uint256 amount, bytes calldata royaltyContext, Licensing.LicensingConfig memory licensingConfig, - uint256 mintingFeeByHook + uint256 mintingFeeByHook, + uint256 maxMintingFee ) private returns (address royaltyPolicy, uint32 royaltyPercent) { - ILicenseTemplate lct = ILicenseTemplate(licenseTemplate); - uint256 mintingFeeByLicense = 0; - address currencyToken = address(0); - (royaltyPolicy, royaltyPercent, mintingFeeByLicense, currencyToken) = lct.getRoyaltyPolicy(licenseTermsId); + RoyaltyPolicyInfo memory royaltyInfo = _getRoyaltyPolicyInfo(licenseTemplate, licenseTermsId); + royaltyPolicy = royaltyInfo.royaltyPolicy; + royaltyPercent = royaltyInfo.royaltyPercent; // override royalty percent if it is set in licensing config if (licensingConfig.isSet && licensingConfig.commercialRevShare != 0) { royaltyPercent = licensingConfig.commercialRevShare; } if (royaltyPolicy != address(0)) { ROYALTY_MODULE.onLicenseMinting(parentIpId, royaltyPolicy, royaltyPercent, royaltyContext); - uint256 tmf = _getTotalMintingFee(licensingConfig, mintingFeeByHook, mintingFeeByLicense, amount); + uint256 tmf = _getTotalMintingFee( + licensingConfig, + mintingFeeByHook, + royaltyInfo.mintingFeeByLicense, + amount + ); + if (maxMintingFee != 0 && tmf > maxMintingFee) { + revert Errors.LicensingModule__MintingFeeExceedMaxMintingFee(tmf, maxMintingFee); + } // pay minting fee if (tmf > 0) { - ROYALTY_MODULE.payLicenseMintingFee(parentIpId, msg.sender, currencyToken, tmf); + ROYALTY_MODULE.payLicenseMintingFee(parentIpId, msg.sender, royaltyInfo.currencyToken, tmf); } } } + /// @dev get royalty policy info from given license terms + /// @param licenseTemplate The address of the license template. + /// @param licenseTermsId The ID of the license terms. + /// @return RoyaltyPolicyInfo The royalty policy info + function _getRoyaltyPolicyInfo( + address licenseTemplate, + uint256 licenseTermsId + ) private view returns (RoyaltyPolicyInfo memory) { + ( + address royaltyPolicy, + uint32 royaltyPercent, + uint256 mintingFeeByLicense, + address currencyToken + ) = ILicenseTemplate(licenseTemplate).getRoyaltyPolicy(licenseTermsId); + return RoyaltyPolicyInfo(royaltyPolicy, royaltyPercent, mintingFeeByLicense, currencyToken); + } + /// @dev get total minting fee /// There are 3 places to get the minting fee: license terms, MintingLicenseConfig, MintingFeeModule /// The order of priority is MintingFeeModule > MintingLicenseConfig > > license terms diff --git a/test/foundry/integration/big-bang/SingleNftCollection.t.sol b/test/foundry/integration/big-bang/SingleNftCollection.t.sol index 1dad51235..2ba4b185a 100644 --- a/test/foundry/integration/big-bang/SingleNftCollection.t.sol +++ b/test/foundry/integration/big-bang/SingleNftCollection.t.sol @@ -153,7 +153,8 @@ contract BigBang_Integration_SingleNftCollection is BaseIntegration { licenseTermsId: commDerivTermsId, amount: 1, receiver: u.carl, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); ipAcct[6] = registerIpAccount(mockNFT, 6, u.carl); @@ -178,7 +179,8 @@ contract BigBang_Integration_SingleNftCollection is BaseIntegration { licenseTermsId: ncSocialRemixTermsId, amount: 1, receiver: u.carl, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); ipAcct[tokenId] = registerIpAccount(address(mockNFT), tokenId, u.carl); @@ -207,7 +209,8 @@ contract BigBang_Integration_SingleNftCollection is BaseIntegration { licenseTermsId: commDerivTermsId, amount: 2, receiver: u.alice, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); // ID 0 (first license) ipAcct[2] = registerIpAccount(mockNFT, 2, u.alice); @@ -243,7 +246,8 @@ contract BigBang_Integration_SingleNftCollection is BaseIntegration { licenseTermsId: commDerivTermsId, amount: license0_mintAmount, receiver: u.carl, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); // NC Social Remix license @@ -253,7 +257,8 @@ contract BigBang_Integration_SingleNftCollection is BaseIntegration { licenseTermsId: ncSocialRemixTermsId, // ipAcct[3] has this policy attached amount: 1, receiver: u.carl, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); ipAcct[tokenId] = registerIpAccount(address(mockNFT), tokenId, u.carl); @@ -278,7 +283,8 @@ contract BigBang_Integration_SingleNftCollection is BaseIntegration { licenseTermsId: commDerivTermsId, amount: license1_mintAmount, receiver: u.carl, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); carl_licenses[1] = carl_licenses[1] + license1_mintAmount - 1; // use last license ID minted from above diff --git a/test/foundry/integration/flows/disputes/Disputes.t.sol b/test/foundry/integration/flows/disputes/Disputes.t.sol index 823662489..25f430d1d 100644 --- a/test/foundry/integration/flows/disputes/Disputes.t.sol +++ b/test/foundry/integration/flows/disputes/Disputes.t.sol @@ -55,7 +55,8 @@ contract Flows_Integration_Disputes is BaseIntegration { licenseTermsId: ncSocialRemixTermsId, amount: 1, receiver: u.carl, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.balanceOf(u.carl), 1); @@ -69,7 +70,8 @@ contract Flows_Integration_Disputes is BaseIntegration { licenseTermsId: ncSocialRemixTermsId, amount: 1, receiver: u.carl, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); } @@ -83,7 +85,8 @@ contract Flows_Integration_Disputes is BaseIntegration { licenseTermsId: ncSocialRemixTermsId, amount: 1, receiver: u.carl, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.balanceOf(u.carl), 1); @@ -113,7 +116,8 @@ contract Flows_Integration_Disputes is BaseIntegration { parentIpIds: parentIpIds, licenseTermsIds: licenseTermsIds, licenseTemplate: address(pilTemplate), - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); } @@ -127,7 +131,8 @@ contract Flows_Integration_Disputes is BaseIntegration { licenseTermsId: ncSocialRemixTermsId, amount: 1, receiver: u.carl, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.balanceOf(u.carl), 1); @@ -154,7 +159,8 @@ contract Flows_Integration_Disputes is BaseIntegration { licenseTermsId: ncSocialRemixTermsId, amount: 1, receiver: u.carl, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.balanceOf(u.carl), 1); } diff --git a/test/foundry/integration/flows/grouping/Grouping.t.sol b/test/foundry/integration/flows/grouping/Grouping.t.sol index 89c6fcbdc..49cc5916e 100644 --- a/test/foundry/integration/flows/grouping/Grouping.t.sol +++ b/test/foundry/integration/flows/grouping/Grouping.t.sol @@ -80,8 +80,8 @@ contract Flows_Integration_Grouping is BaseIntegration { vm.stopPrank(); } - licensingModule.mintLicenseTokens(ipAcct[1], address(pilTemplate), commRemixTermsId, 1, address(this), ""); - licensingModule.mintLicenseTokens(ipAcct[2], address(pilTemplate), commRemixTermsId, 1, address(this), ""); + licensingModule.mintLicenseTokens(ipAcct[1], address(pilTemplate), commRemixTermsId, 1, address(this), "", 0); + licensingModule.mintLicenseTokens(ipAcct[2], address(pilTemplate), commRemixTermsId, 1, address(this), "", 0); { address[] memory ipIds = new address[](2); ipIds[0] = ipAcct[1]; @@ -98,7 +98,7 @@ contract Flows_Integration_Grouping is BaseIntegration { parentIpIds[0] = groupId; uint256[] memory licenseIds = new uint256[](1); licenseIds[0] = commRemixTermsId; - licensingModule.registerDerivative(ipAcct[3], parentIpIds, licenseIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipAcct[3], parentIpIds, licenseIds, address(pilTemplate), "", 0); vm.stopPrank(); } diff --git a/test/foundry/integration/flows/licensing/LicensingIntegration.t.sol b/test/foundry/integration/flows/licensing/LicensingIntegration.t.sol index 35ef94c68..564fa632a 100644 --- a/test/foundry/integration/flows/licensing/LicensingIntegration.t.sol +++ b/test/foundry/integration/flows/licensing/LicensingIntegration.t.sol @@ -122,7 +122,7 @@ contract LicensingIntegrationTest is BaseIntegration { parentIpIds[0] = ipAcct[1]; licenseTermsIds[0] = 1; - licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); assertEq(licenseRegistry.hasIpAttachedLicenseTerms(ipAcct[2], address(pilTemplate), 1), true); assertEq(licenseRegistry.getAttachedLicenseTermsCount(ipAcct[2]), 2); @@ -145,7 +145,8 @@ contract LicensingIntegrationTest is BaseIntegration { 1, 1, address(u.carl), - "" + "", + 0 ); assertEq(licenseToken.ownerOf(lcTokenId), u.carl); assertEq(licenseToken.getLicenseTermsId(lcTokenId), 1); @@ -182,7 +183,7 @@ contract LicensingIntegrationTest is BaseIntegration { erc20.mint(u.dan, 1000); erc20.approve(address(royaltyModule), 100); - lcTokenId = licensingModule.mintLicenseTokens(ipAcct[1], address(pilTemplate), 2, 1, address(u.dan), ""); + lcTokenId = licensingModule.mintLicenseTokens(ipAcct[1], address(pilTemplate), 2, 1, address(u.dan), "", 0); assertEq(licenseToken.ownerOf(lcTokenId), u.dan); assertEq(licenseToken.getLicenseTermsId(lcTokenId), 2); @@ -225,7 +226,7 @@ contract LicensingIntegrationTest is BaseIntegration { parentIpIds[0] = ipAcct[1]; licenseTermsIds[0] = 2; - licensingModule.registerDerivative(ipAcct[7], parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipAcct[7], parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); assertEq(licenseRegistry.hasIpAttachedLicenseTerms(ipAcct[7], address(pilTemplate), 2), true); assertEq(licenseRegistry.getAttachedLicenseTermsCount(ipAcct[7]), 2); @@ -272,7 +273,8 @@ contract LicensingIntegrationTest is BaseIntegration { parentIpIds: parentIpIds, licenseTermsIds: licenseTermsIds, licenseTemplate: address(anotherPILTemplate), - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); } @@ -318,7 +320,8 @@ contract LicensingIntegrationTest is BaseIntegration { parentIpIds: parentIpIds, licenseTermsIds: licenseTermsIds, licenseTemplate: address(pilTemplate), - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); } } diff --git a/test/foundry/integration/flows/licensing/LicensingScenarios.t.sol b/test/foundry/integration/flows/licensing/LicensingScenarios.t.sol index b79ceee96..868135026 100644 --- a/test/foundry/integration/flows/licensing/LicensingScenarios.t.sol +++ b/test/foundry/integration/flows/licensing/LicensingScenarios.t.sol @@ -138,7 +138,8 @@ contract Licensing_Scenarios is BaseIntegration { licenseTermsId: ncSocialRemixTermsId, amount: 1, receiver: u.bob, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); licensingModule.registerDerivativeWithLicenseTokens(ipAcct[2], licenseIds, ""); @@ -150,7 +151,8 @@ contract Licensing_Scenarios is BaseIntegration { licenseTermsId: commTermsId, amount: 1, receiver: u.bob, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); licensingModule.registerDerivativeWithLicenseTokens(ipAcct[3], licenseIds, ""); @@ -162,7 +164,8 @@ contract Licensing_Scenarios is BaseIntegration { licenseTermsId: commRemixTermsId, amount: 1, receiver: u.bob, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); licensingModule.registerDerivativeWithLicenseTokens(ipAcct[4], licenseIds, ""); diff --git a/test/foundry/integration/flows/royalty/Royalty.t.sol b/test/foundry/integration/flows/royalty/Royalty.t.sol index 836c8c624..9ae02220d 100644 --- a/test/foundry/integration/flows/royalty/Royalty.t.sol +++ b/test/foundry/integration/flows/royalty/Royalty.t.sol @@ -80,7 +80,8 @@ contract Flows_Integration_Disputes is BaseIntegration { licenseTermsId: commRemixTermsId, amount: mintAmount, receiver: u.bob, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); // first license minted licenseIds[1] = licenseIds[0] + 1; // second license minted licenseIds[2] = licenseIds[0] + 2; // third license minted @@ -131,7 +132,8 @@ contract Flows_Integration_Disputes is BaseIntegration { licenseTermsId: commRemixTermsId, amount: mintAmount, receiver: u.carl, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); vm.expectEmit(address(royaltyModule)); @@ -148,7 +150,8 @@ contract Flows_Integration_Disputes is BaseIntegration { licenseTermsId: commRemixTermsId, amount: mintAmount, receiver: u.carl, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); ipAcct[3] = registerIpAccount(address(mockNFT), 3, u.carl); @@ -247,7 +250,8 @@ contract Flows_Integration_Disputes is BaseIntegration { licenseTermsId: commRemixExternalTermsId, amount: 1, receiver: u.alice, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); mockNFT.mintId(u.alice, 5); diff --git a/test/foundry/invariants/DisputeModule.t.sol b/test/foundry/invariants/DisputeModule.t.sol index cff04c07d..14c5af02b 100644 --- a/test/foundry/invariants/DisputeModule.t.sol +++ b/test/foundry/invariants/DisputeModule.t.sol @@ -180,7 +180,8 @@ contract DisputeInvariants is BaseTest { parentIpIds: parentIpIds, licenseTermsIds: licenseTermsIds, licenseTemplate: address(pilTemplate), - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); /* targetContract(address(harness)); diff --git a/test/foundry/invariants/LicensingModule.t.sol b/test/foundry/invariants/LicensingModule.t.sol index 254e0fade..457a2fd92 100644 --- a/test/foundry/invariants/LicensingModule.t.sol +++ b/test/foundry/invariants/LicensingModule.t.sol @@ -75,7 +75,8 @@ contract LicensingModuleHarness is Test { licenseTermsId, amount, receiver, - royaltyContext + royaltyContext, + 0 ); mintedOrRegisterDerivative = true; @@ -102,7 +103,7 @@ contract LicensingModuleHarness is Test { require(parentIpIdsNth[i] < availableIpIds.length, "LicensingModuleHarness: invalid parentIpIdsNth"); parentIpIds[i] = availableIpIds[parentIpIdsNth[i]]; } - licensingModule.registerDerivative(childIpId, parentIpIds, licenseTermsIds, licenseTemplate, royaltyContext); + licensingModule.registerDerivative(childIpId, parentIpIds, licenseTermsIds, licenseTemplate, royaltyContext, 0); mintedOrRegisterDerivative = true; } diff --git a/test/foundry/modules/dispute/DisputeModule.t.sol b/test/foundry/modules/dispute/DisputeModule.t.sol index 1ef2b02c5..8e0f75853 100644 --- a/test/foundry/modules/dispute/DisputeModule.t.sol +++ b/test/foundry/modules/dispute/DisputeModule.t.sol @@ -97,7 +97,8 @@ contract DisputeModuleTest is BaseTest { licenseTermsId: getSelectedPILicenseTermsId("cheap_flexible"), amount: mintAmount, receiver: u.bob, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); // first license minted ipAddr2 = ipAssetRegistry.register(block.chainid, address(mockNFT), 1); diff --git a/test/foundry/modules/grouping/EvenSplitGroupPool.t.sol b/test/foundry/modules/grouping/EvenSplitGroupPool.t.sol index 332e3dca3..2175669f1 100644 --- a/test/foundry/modules/grouping/EvenSplitGroupPool.t.sol +++ b/test/foundry/modules/grouping/EvenSplitGroupPool.t.sol @@ -169,7 +169,7 @@ contract EvenSplitGroupPoolTest is BaseTest { vm.prank(ipOwner1); licensingModule.attachLicenseTerms(ipId1, address(pilTemplate), commRemixTermsId); - licensingModule.mintLicenseTokens(ipId1, address(pilTemplate), commRemixTermsId, 1, address(this), ""); + licensingModule.mintLicenseTokens(ipId1, address(pilTemplate), commRemixTermsId, 1, address(this), "", 0); vm.prank(address(groupingModule)); rewardPool.addIp(group1, ipId1); diff --git a/test/foundry/modules/grouping/GroupingModule.t.sol b/test/foundry/modules/grouping/GroupingModule.t.sol index b9cd4cba7..72db67299 100644 --- a/test/foundry/modules/grouping/GroupingModule.t.sol +++ b/test/foundry/modules/grouping/GroupingModule.t.sol @@ -171,10 +171,10 @@ contract GroupingModuleTest is BaseTest { vm.prank(ipOwner1); licensingModule.attachLicenseTerms(ipId1, address(pilTemplate), termsId); - licensingModule.mintLicenseTokens(ipId1, address(pilTemplate), termsId, 1, address(this), ""); + licensingModule.mintLicenseTokens(ipId1, address(pilTemplate), termsId, 1, address(this), "", 0); vm.prank(ipOwner2); licensingModule.attachLicenseTerms(ipId2, address(pilTemplate), termsId); - licensingModule.mintLicenseTokens(ipId2, address(pilTemplate), termsId, 1, address(this), ""); + licensingModule.mintLicenseTokens(ipId2, address(pilTemplate), termsId, 1, address(this), "", 0); vm.startPrank(alice); licensingModule.attachLicenseTerms(groupId, address(pilTemplate), termsId); @@ -191,7 +191,7 @@ contract GroupingModuleTest is BaseTest { uint256[] memory licenseTermsIds = new uint256[](1); licenseTermsIds[0] = termsId; vm.prank(ipOwner3); - licensingModule.registerDerivative(ipId3, parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipId3, parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); erc20.mint(ipOwner3, 1000); vm.startPrank(ipOwner3); @@ -284,7 +284,7 @@ contract GroupingModuleTest is BaseTest { parentIpIds[0] = groupId; licenseTermsIds[0] = termsId; - licensingModule.registerDerivative(ipId3, parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipId3, parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); vm.stopPrank(); address[] memory ipIds = new address[](2); @@ -337,7 +337,7 @@ contract GroupingModuleTest is BaseTest { parentIpIds[0] = groupId; licenseTermsIds[0] = termsId; - licensingModule.registerDerivative(ipId3, parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipId3, parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); vm.stopPrank(); address[] memory removeIpIds = new address[](1); diff --git a/test/foundry/modules/licensing/LicensingModule.t.sol b/test/foundry/modules/licensing/LicensingModule.t.sol index ce886ca4c..13ede9159 100644 --- a/test/foundry/modules/licensing/LicensingModule.t.sol +++ b/test/foundry/modules/licensing/LicensingModule.t.sol @@ -209,7 +209,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner2, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.ownerOf(lcTokenId), ipOwner2); assertEq(licenseToken.getLicenseTermsId(lcTokenId), termsId); @@ -250,7 +251,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: address(ipOwner2), - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); vm.warp(11 days); @@ -338,7 +340,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: receiver, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.ownerOf(lcTokenId), receiver); assertEq(licenseToken.getLicenseTermsId(lcTokenId), termsId); @@ -350,6 +353,117 @@ contract LicensingModuleTest is BaseTest { assertEq(licenseToken.balanceOf(receiver), 1); } + function test_LicensingModule_mintLicenseTokens_EqualsMaxMintingFee() public { + uint256 termsId = pilTemplate.registerLicenseTerms( + PILFlavors.commercialRemix({ + mintingFee: 100, + commercialRevShare: 10_000_000, + royaltyPolicy: address(royaltyPolicyLAP), + currencyToken: address(erc20) + }) + ); + vm.prank(ipOwner1); + licensingModule.attachLicenseTerms(ipId1, address(pilTemplate), termsId); + + vm.startPrank(ipOwner2); + erc20.mint(ipOwner2, 1000); + erc20.approve(address(royaltyModule), 100); + + address receiver = address(0x111); + vm.expectEmit(); + emit ILicensingModule.LicenseTokensMinted(ipOwner2, ipId1, address(pilTemplate), termsId, 1, receiver, 0); + uint256 lcTokenId = licensingModule.mintLicenseTokens({ + licensorIpId: ipId1, + licenseTemplate: address(pilTemplate), + licenseTermsId: termsId, + amount: 1, + receiver: receiver, + royaltyContext: "", + maxMintingFee: 100 + }); + vm.stopPrank(); + assertEq(licenseToken.ownerOf(lcTokenId), receiver); + assertEq(licenseToken.getLicenseTermsId(lcTokenId), termsId); + assertEq(licenseToken.getLicenseTemplate(lcTokenId), address(pilTemplate)); + assertEq(licenseToken.getLicensorIpId(lcTokenId), ipId1); + assertEq(licenseToken.tokenOfOwnerByIndex(receiver, 0), lcTokenId); + assertEq(licenseToken.totalMintedTokens(), 1); + assertEq(licenseToken.totalSupply(), 1); + assertEq(licenseToken.balanceOf(receiver), 1); + } + + function test_LicensingModule_mintLicenseTokens_LessThanMaxMintingFee() public { + uint256 termsId = pilTemplate.registerLicenseTerms( + PILFlavors.commercialRemix({ + mintingFee: 100, + commercialRevShare: 10_000_000, + royaltyPolicy: address(royaltyPolicyLAP), + currencyToken: address(erc20) + }) + ); + vm.prank(ipOwner1); + licensingModule.attachLicenseTerms(ipId1, address(pilTemplate), termsId); + + vm.startPrank(ipOwner2); + erc20.mint(ipOwner2, 1000); + erc20.approve(address(royaltyModule), 100); + + address receiver = address(0x111); + vm.expectEmit(); + emit ILicensingModule.LicenseTokensMinted(ipOwner2, ipId1, address(pilTemplate), termsId, 1, receiver, 0); + uint256 lcTokenId = licensingModule.mintLicenseTokens({ + licensorIpId: ipId1, + licenseTemplate: address(pilTemplate), + licenseTermsId: termsId, + amount: 1, + receiver: receiver, + royaltyContext: "", + maxMintingFee: 1000 + }); + vm.stopPrank(); + assertEq(erc20.balanceOf(ipOwner2), 900); + assertEq(licenseToken.ownerOf(lcTokenId), receiver); + assertEq(licenseToken.getLicenseTermsId(lcTokenId), termsId); + assertEq(licenseToken.getLicenseTemplate(lcTokenId), address(pilTemplate)); + assertEq(licenseToken.getLicensorIpId(lcTokenId), ipId1); + assertEq(licenseToken.tokenOfOwnerByIndex(receiver, 0), lcTokenId); + assertEq(licenseToken.totalMintedTokens(), 1); + assertEq(licenseToken.totalSupply(), 1); + assertEq(licenseToken.balanceOf(receiver), 1); + } + + function test_LicensingModule_revert_mintLicenseTokens_ExceededMaxMintingFee() public { + uint256 termsId = pilTemplate.registerLicenseTerms( + PILFlavors.commercialRemix({ + mintingFee: 1000, + commercialRevShare: 10_000_000, + royaltyPolicy: address(royaltyPolicyLAP), + currencyToken: address(erc20) + }) + ); + vm.prank(ipOwner1); + licensingModule.attachLicenseTerms(ipId1, address(pilTemplate), termsId); + + vm.startPrank(ipOwner2); + erc20.mint(ipOwner2, 1000); + erc20.approve(address(royaltyModule), 1000); + + address receiver = address(0x111); + vm.expectRevert( + abi.encodeWithSelector(Errors.LicensingModule__MintingFeeExceedMaxMintingFee.selector, 1000, 100) + ); + uint256 lcTokenId = licensingModule.mintLicenseTokens({ + licensorIpId: ipId1, + licenseTemplate: address(pilTemplate), + licenseTermsId: termsId, + amount: 1, + receiver: receiver, + royaltyContext: "", + maxMintingFee: 100 + }); + vm.stopPrank(); + } + function test_LicensingModule_mintLicenseTokens_mintMultipleTokens() public { uint256 termsId = pilTemplate.registerLicenseTerms(PILFlavors.defaultValuesLicenseTerms()); vm.prank(ipOwner1); @@ -364,7 +478,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 2, receiver: receiver, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.ownerOf(firstTokenId), receiver); assertEq(licenseToken.getLicenseTermsId(firstTokenId), termsId); @@ -384,6 +499,37 @@ contract LicensingModuleTest is BaseTest { assertEq(licenseToken.balanceOf(receiver), 2); } + function test_LicensingModule_revert_mintLicenseTokens_mintMultipleTokens_ExceededMaxMintingFee() public { + uint256 termsId = pilTemplate.registerLicenseTerms( + PILFlavors.commercialRemix({ + mintingFee: 1000, + commercialRevShare: 10_000_000, + royaltyPolicy: address(royaltyPolicyLAP), + currencyToken: address(erc20) + }) + ); + vm.prank(ipOwner1); + licensingModule.attachLicenseTerms(ipId1, address(pilTemplate), termsId); + + vm.startPrank(ipOwner2); + erc20.mint(ipOwner2, 2000); + erc20.approve(address(royaltyModule), 2000); + + address receiver = address(0x111); + vm.expectRevert( + abi.encodeWithSelector(Errors.LicensingModule__MintingFeeExceedMaxMintingFee.selector, 2000, 1500) + ); + uint256 firstTokenId = licensingModule.mintLicenseTokens({ + licensorIpId: ipId1, + licenseTemplate: address(pilTemplate), + licenseTermsId: termsId, + amount: 2, + receiver: receiver, + royaltyContext: "", + maxMintingFee: 1500 + }); + } + function test_LicensingModule_mintLicenseTokens_mintMultipleTimes() public { uint256 termsId = pilTemplate.registerLicenseTerms(PILFlavors.defaultValuesLicenseTerms()); vm.prank(ipOwner1); @@ -407,7 +553,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: receiver, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.ownerOf(tokenId), receiver); assertEq(licenseToken.getLicenseTermsId(tokenId), termsId); @@ -453,7 +600,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner2, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.ownerOf(lcTokenId), ipOwner2); assertEq(licenseToken.getLicenseTermsId(lcTokenId), termsId); @@ -476,7 +624,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: address(0x777), - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); } @@ -493,7 +642,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 0, receiver: receiver, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); vm.expectRevert(Errors.LicensingModule__ReceiverZeroAddress.selector); @@ -503,7 +653,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: address(0), - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); } @@ -524,7 +675,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: receiver, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); } @@ -540,7 +692,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: 9999, amount: 1, receiver: receiver, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); } @@ -561,7 +714,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 2, receiver: receiver, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); } @@ -575,7 +729,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: receiver, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.ownerOf(lcTokenId), receiver); assertEq(licenseToken.getLicenseTermsId(lcTokenId), termsId); @@ -606,7 +761,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner2, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.ownerOf(lcTokenId), ipOwner2); assertEq(licenseToken.getLicenseTermsId(lcTokenId), termsId); @@ -659,7 +815,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner2, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseRegistry.hasIpAttachedLicenseTerms(ipId1, address(pilTemplate), termsId), false); @@ -719,7 +876,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner2, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); vm.prank(u.admin); @@ -761,7 +919,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner3, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); uint256 lcTokenId2 = licensingModule.mintLicenseTokens({ @@ -770,7 +929,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner3, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.ownerOf(lcTokenId1), ipOwner3); @@ -835,7 +995,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner1, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); uint256[] memory licenseTokens = new uint256[](1); @@ -862,7 +1023,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: expiredTermsId, amount: 1, receiver: ipOwner3, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); uint256 lcTokenId2 = licensingModule.mintLicenseTokens({ @@ -871,7 +1033,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: expiredTermsId, amount: 1, receiver: ipOwner3, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.ownerOf(lcTokenId1), ipOwner3); @@ -927,7 +1090,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: expiredTermsId, amount: 1, receiver: ipOwner5, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); vm.warp(11 days); @@ -959,7 +1123,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner1, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); uint256[] memory licenseTokens = new uint256[](1); @@ -999,7 +1164,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner2, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); uint256 lcTokenId2 = licensingModule.mintLicenseTokens({ @@ -1008,7 +1174,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner3, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); uint256[] memory licenseTokens = new uint256[](1); @@ -1052,7 +1219,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner3, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); uint256 lcTokenId2 = licensingModule.mintLicenseTokens({ @@ -1061,7 +1229,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner3, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); uint256[] memory licenseTokens = new uint256[](1); @@ -1097,7 +1266,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner2, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); uint256[] memory licenseTokens = new uint256[](1); @@ -1126,7 +1296,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipId3, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); uint256[] memory licenseTokens = new uint256[](1); @@ -1155,7 +1326,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner2, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); uint256[] memory licenseTokens = new uint256[](1); @@ -1193,7 +1365,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner2, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); vm.prank(ipOwner2); @@ -1262,7 +1435,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner2, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.ownerOf(lcTokenId), ipOwner2); @@ -1317,7 +1491,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner2, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); } @@ -1358,7 +1533,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner2, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); assertEq(licenseToken.ownerOf(lcTokenId), ipOwner2); assertEq(licenseToken.getLicenseTermsId(lcTokenId), termsId); @@ -1395,7 +1571,7 @@ contract LicensingModuleTest is BaseTest { function test_LicensingModule_registerDerivative_revert_emptyParentIpIds() public { vm.expectRevert(Errors.LicensingModule__NoParentIp.selector); vm.prank(ipOwner2); - licensingModule.registerDerivative(ipId2, new address[](0), new uint256[](0), address(0), ""); + licensingModule.registerDerivative(ipId2, new address[](0), new uint256[](0), address(0), "", 0); } function test_LicensingModule_registerDerivative_revert_parentIdsLengthMismatchWithLicenseIds() public { @@ -1403,7 +1579,7 @@ contract LicensingModuleTest is BaseTest { parentIpIds[0] = ipId1; vm.expectRevert(abi.encodeWithSelector(Errors.LicensingModule__LicenseTermsLengthMismatch.selector, 1, 0)); vm.prank(ipOwner2); - licensingModule.registerDerivative(ipId2, parentIpIds, new uint256[](0), address(0), ""); + licensingModule.registerDerivative(ipId2, parentIpIds, new uint256[](0), address(0), "", 0); } function test_LicensingModule_registerDerivative_revert_IncompatibleLicenses() public { @@ -1441,7 +1617,7 @@ contract LicensingModuleTest is BaseTest { abi.encodeWithSelector(Errors.LicensingModule__LicenseNotCompatibleForDerivative.selector, ipId3) ); vm.prank(ipOwner3); - licensingModule.registerDerivative(ipId3, parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipId3, parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); } function test_LicensingModule_registerDerivative_revert_NotAllowDerivativesReciprocal() public { @@ -1462,7 +1638,7 @@ contract LicensingModuleTest is BaseTest { licenseTermsIds[0] = socialRemixTermsId; vm.prank(ipOwner2); - licensingModule.registerDerivative(ipId2, parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipId2, parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); // register derivative of derivative, should revert parentIpIds = new address[](1); @@ -1472,7 +1648,7 @@ contract LicensingModuleTest is BaseTest { abi.encodeWithSelector(Errors.LicensingModule__LicenseNotCompatibleForDerivative.selector, ipId3) ); vm.prank(ipOwner3); - licensingModule.registerDerivative(ipId3, parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipId3, parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); } function test_LicensingModule_setLicensingConfig() public { @@ -1577,7 +1753,7 @@ contract LicensingModuleTest is BaseTest { licenseTermsIds[0] = termsId; // register derivative vm.prank(ipOwner2); - licensingModule.registerDerivative(ipId2, parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipId2, parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); Licensing.LicensingConfig memory licensingConfig = Licensing.LicensingConfig({ isSet: true, @@ -1600,7 +1776,7 @@ contract LicensingModuleTest is BaseTest { parentIpIds = new address[](1); parentIpIds[0] = ipId2; vm.prank(ipOwner3); - licensingModule.registerDerivative(ipId3, parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipId3, parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); erc20.mint(ipOwner3, 1000); vm.startPrank(ipOwner3); @@ -1807,7 +1983,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: receiver, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); } @@ -1864,7 +2041,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 5, receiver: receiver, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); vm.stopPrank(); @@ -1922,7 +2100,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 5, receiver: receiver, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); vm.stopPrank(); @@ -1970,7 +2149,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 5, receiver: receiver, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); vm.stopPrank(); @@ -2021,7 +2201,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: receiver, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); vm.stopPrank(); @@ -2073,7 +2254,7 @@ contract LicensingModuleTest is BaseTest { licenseTermsIds, address(pilTemplate) ); - licensingModule.registerDerivative(ipId2, parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipId2, parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); vm.stopPrank(); assertEq(erc20.balanceOf(ipOwner2), 900); @@ -2126,7 +2307,7 @@ contract LicensingModuleTest is BaseTest { licenseTermsIds, address(pilTemplate) ); - licensingModule.registerDerivative(ipId2, parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipId2, parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); vm.stopPrank(); assertEq(erc20.balanceOf(ipOwner2), 900); @@ -2153,7 +2334,8 @@ contract LicensingModuleTest is BaseTest { licenseTermsId: termsId, amount: 1, receiver: ipOwner2, - royaltyContext: "" + royaltyContext: "", + maxMintingFee: 0 }); vm.stopPrank(); assertEq(erc20.balanceOf(ipOwner2), 900 - 300); @@ -2191,7 +2373,7 @@ contract LicensingModuleTest is BaseTest { licenseTermsIds[0] = termsId; vm.prank(ipOwner2); vm.expectRevert("MockLicensingHook: caller is invalid"); - licensingModule.registerDerivative(ipId2, parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipId2, parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); } function onERC721Received(address, address, uint256, bytes memory) public pure returns (bytes4) { diff --git a/test/foundry/modules/licensing/PILicenseTemplate.t.sol b/test/foundry/modules/licensing/PILicenseTemplate.t.sol index 7a6fe0d5a..3fab2c938 100644 --- a/test/foundry/modules/licensing/PILicenseTemplate.t.sol +++ b/test/foundry/modules/licensing/PILicenseTemplate.t.sol @@ -334,7 +334,7 @@ contract PILicenseTemplateTest is BaseTest { uint256[] memory licenseTermsIds = new uint256[](1); licenseTermsIds[0] = commUseTermsId; vm.prank(ipOwner[2]); - licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); uint256 anotherTermsId = pilTemplate.registerLicenseTerms( PILFlavors.commercialRemix({ @@ -365,7 +365,7 @@ contract PILicenseTemplateTest is BaseTest { uint256[] memory licenseTermsIds = new uint256[](1); licenseTermsIds[0] = commUseTermsId; vm.prank(ipOwner[2]); - licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); bool result = pilTemplate.verifyMintLicenseToken(commUseTermsId, ipOwner[3], ipAcct[2], 1); assertFalse(result); @@ -412,7 +412,7 @@ contract PILicenseTemplateTest is BaseTest { uint256[] memory licenseTermsIds = new uint256[](1); licenseTermsIds[0] = socialRemixTermsId; vm.prank(ipOwner[2]); - licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); // checking register derivative of derivative, expect false bool result = pilTemplate.verifyRegisterDerivative(ipAcct[3], ipAcct[2], socialRemixTermsId, ipOwner[3]); diff --git a/test/foundry/registries/LicenseRegistry.t.sol b/test/foundry/registries/LicenseRegistry.t.sol index 1cd7d9cd3..a65a63d0d 100644 --- a/test/foundry/registries/LicenseRegistry.t.sol +++ b/test/foundry/registries/LicenseRegistry.t.sol @@ -175,7 +175,7 @@ contract LicenseRegistryTest is BaseTest { uint256[] memory licenseTermsIds = new uint256[](1); licenseTermsIds[0] = socialRemixTermsId; vm.prank(ipOwner[2]); - licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); uint256 defaultTermsId = pilTemplate.registerLicenseTerms(PILFlavors.defaultValuesLicenseTerms()); vm.expectRevert(Errors.LicensingModule__DerivativesCannotAddLicenseTerms.selector); @@ -212,7 +212,7 @@ contract LicenseRegistryTest is BaseTest { uint256[] memory licenseTermsIds = new uint256[](1); licenseTermsIds[0] = socialRemixTermsId; vm.prank(ipOwner[2]); - licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); vm.expectRevert(abi.encodeWithSelector(Errors.LicenseRegistry__IndexOutOfBounds.selector, ipAcct[1], 1, 1)); licenseRegistry.getDerivativeIp(ipAcct[1], 1); @@ -228,7 +228,7 @@ contract LicenseRegistryTest is BaseTest { uint256[] memory licenseTermsIds = new uint256[](1); licenseTermsIds[0] = socialRemixTermsId; vm.prank(ipOwner[2]); - licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), ""); + licensingModule.registerDerivative(ipAcct[2], parentIpIds, licenseTermsIds, address(pilTemplate), "", 0); vm.expectRevert(abi.encodeWithSelector(Errors.LicenseRegistry__IndexOutOfBounds.selector, ipAcct[2], 1, 1)); licenseRegistry.getParentIp(ipAcct[2], 1);