From 55603cd088d7ca43324b52aa5bb10443e8b1f874 Mon Sep 17 00:00:00 2001 From: Spablob Date: Fri, 12 Apr 2024 15:34:52 +0300 Subject: [PATCH 1/3] royalty fixes --- .../royalty/policies/IIpRoyaltyVault.sol | 4 +- contracts/lib/Errors.sol | 2 + contracts/modules/royalty/RoyaltyModule.sol | 3 +- .../royalty/policies/IpRoyaltyVault.sol | 50 +-- .../royalty/policies/RoyaltyPolicyLAP.sol | 7 +- .../modules/royalty/RoyaltyModule.t.sol | 284 ++++-------------- .../modules/royalty/RoyaltyPolicyLAP.t.sol | 50 +-- 7 files changed, 122 insertions(+), 278 deletions(-) diff --git a/contracts/interfaces/modules/royalty/policies/IIpRoyaltyVault.sol b/contracts/interfaces/modules/royalty/policies/IIpRoyaltyVault.sol index ecfed7922..079a7fe35 100644 --- a/contracts/interfaces/modules/royalty/policies/IIpRoyaltyVault.sol +++ b/contracts/interfaces/modules/royalty/policies/IIpRoyaltyVault.sol @@ -52,8 +52,8 @@ interface IIpRoyaltyVault { /// @notice Allows token holders to claim revenue token based on the token balance at certain snapshot /// @param snapshotId The snapshot id - /// @param tokens The list of revenue tokens to claim - function claimRevenueByTokenBatch(uint256 snapshotId, address[] calldata tokens) external; + /// @param tokenList The list of revenue tokens to claim + function claimRevenueByTokenBatch(uint256 snapshotId, address[] calldata tokenList) external; /// @notice Allows token holders to claim by a list of snapshot ids based on the token balance at certain snapshot /// @param snapshotIds The list of snapshot ids diff --git a/contracts/lib/Errors.sol b/contracts/lib/Errors.sol index 622dd67c7..59e02bd11 100644 --- a/contracts/lib/Errors.sol +++ b/contracts/lib/Errors.sol @@ -254,6 +254,7 @@ library Errors { error RoyaltyModule__NoParentsOnLinking(); error RoyaltyModule__ZeroDisputeModule(); error RoyaltyModule__IpIsTagged(); + error RoyaltyModule__ZeroAccessManager(); error RoyaltyPolicyLAP__ZeroRoyaltyModule(); error RoyaltyPolicyLAP__ZeroLiquidSplitFactory(); @@ -270,6 +271,7 @@ library Errors { error RoyaltyPolicyLAP__UnlinkableToParents(); error RoyaltyPolicyLAP__LastPositionNotAbleToMintLicense(); error RoyaltyPolicyLAP__ZeroIpRoyaltyVaultBeacon(); + error RoyaltyPolicyLAP__ZeroAccessManager(); error IpRoyaltyVault__ZeroIpId(); error IpRoyaltyVault__ZeroRoyaltyPolicyLAP(); diff --git a/contracts/modules/royalty/RoyaltyModule.sol b/contracts/modules/royalty/RoyaltyModule.sol index cd5f9416e..ec733f151 100644 --- a/contracts/modules/royalty/RoyaltyModule.sol +++ b/contracts/modules/royalty/RoyaltyModule.sol @@ -58,6 +58,7 @@ contract RoyaltyModule is /// @notice initializer for this implementation contract /// @param accessManager The address of the protocol admin roles contract function initialize(address accessManager) external initializer { + if (accessManager == address(0)) revert Errors.RoyaltyModule__ZeroAccessManager(); __AccessManaged_init(accessManager); __ReentrancyGuard_init(); __UUPSUpgradeable_init(); @@ -132,7 +133,7 @@ contract RoyaltyModule is // if the node is a root node, then royaltyPolicyIpId will be address(0) and any type of royalty type can be // selected to mint a license if the node is a derivative node, then the any minted licenses by the derivative - // node should have the same royalty policy as the parent node a derivative node set its royalty policy + // node should have the same royalty policy as the parent node and a derivative node set its royalty policy // immutably in onLinkToParents() function below if (royaltyPolicyIpId != royaltyPolicy && royaltyPolicyIpId != address(0)) revert Errors.RoyaltyModule__CanOnlyMintSelectedPolicy(); diff --git a/contracts/modules/royalty/policies/IpRoyaltyVault.sol b/contracts/modules/royalty/policies/IpRoyaltyVault.sol index d8f57977f..921a64b75 100644 --- a/contracts/modules/royalty/policies/IpRoyaltyVault.sol +++ b/contracts/modules/royalty/policies/IpRoyaltyVault.sol @@ -86,8 +86,6 @@ contract IpRoyaltyVault is IIpRoyaltyVault, ERC20SnapshotUpgradeable, Reentrancy uint32 unclaimedTokens, address ipIdAddress ) external initializer { - if (ipIdAddress == address(0)) revert Errors.IpRoyaltyVault__ZeroIpId(); - IpRoyaltyVaultStorage storage $ = _getIpRoyaltyVaultStorage(); $.ipId = ipIdAddress; @@ -102,6 +100,10 @@ contract IpRoyaltyVault is IIpRoyaltyVault, ERC20SnapshotUpgradeable, Reentrancy __ERC20_init(name, symbol); } + /// @notice Returns the number royalty token decimals + function decimals() public view override returns (uint8) { + return 6; + } /// @notice Adds a new revenue token to the vault /// @param token The address of the revenue token /// @dev Only callable by the royalty policy LAP @@ -125,24 +127,24 @@ contract IpRoyaltyVault is IIpRoyaltyVault, ERC20SnapshotUpgradeable, Reentrancy uint32 unclaimedTokens = $.unclaimedRoyaltyTokens; $.unclaimedAtSnapshot[snapshotId] = unclaimedTokens; - address[] memory tokens = $.tokens.values(); + address[] memory tokenList = $.tokens.values(); - for (uint256 i = 0; i < tokens.length; i++) { - uint256 tokenBalance = IERC20Upgradeable(tokens[i]).balanceOf(address(this)); + for (uint256 i = 0; i < tokenList.length; i++) { + uint256 tokenBalance = IERC20Upgradeable(tokenList[i]).balanceOf(address(this)); if (tokenBalance == 0) { - $.tokens.remove(tokens[i]); + $.tokens.remove(tokenList[i]); continue; } - uint256 newRevenue = tokenBalance - $.claimVaultAmount[tokens[i]] - $.ancestorsVaultAmount[tokens[i]]; + uint256 newRevenue = tokenBalance - $.claimVaultAmount[tokenList[i]] - $.ancestorsVaultAmount[tokenList[i]]; if (newRevenue == 0) continue; uint256 ancestorsTokens = (newRevenue * unclaimedTokens) / totalSupply(); - $.ancestorsVaultAmount[tokens[i]] += ancestorsTokens; + $.ancestorsVaultAmount[tokenList[i]] += ancestorsTokens; uint256 claimableTokens = newRevenue - ancestorsTokens; - $.claimableAtSnapshot[snapshotId][tokens[i]] = claimableTokens; - $.claimVaultAmount[tokens[i]] += claimableTokens; + $.claimableAtSnapshot[snapshotId][tokenList[i]] = claimableTokens; + $.claimVaultAmount[tokenList[i]] += claimableTokens; } emit SnapshotCompleted(snapshotId, block.timestamp, unclaimedTokens); @@ -161,19 +163,19 @@ contract IpRoyaltyVault is IIpRoyaltyVault, ERC20SnapshotUpgradeable, Reentrancy /// @notice Allows token holders to claim revenue token based on the token balance at certain snapshot /// @param snapshotId The snapshot id - /// @param tokens The list of revenue tokens to claim - function claimRevenueByTokenBatch(uint256 snapshotId, address[] calldata tokens) external nonReentrant { + /// @param tokenList The list of revenue tokens to claim + function claimRevenueByTokenBatch(uint256 snapshotId, address[] calldata tokenList) external nonReentrant { IpRoyaltyVaultStorage storage $ = _getIpRoyaltyVaultStorage(); - for (uint256 i = 0; i < tokens.length; i++) { - uint256 claimableToken = _claimableRevenue(msg.sender, snapshotId, tokens[i]); + for (uint256 i = 0; i < tokenList.length; i++) { + uint256 claimableToken = _claimableRevenue(msg.sender, snapshotId, tokenList[i]); if (claimableToken == 0) continue; - $.isClaimedAtSnapshot[snapshotId][msg.sender][tokens[i]] = true; - $.claimVaultAmount[tokens[i]] -= claimableToken; - IERC20Upgradeable(tokens[i]).safeTransfer(msg.sender, claimableToken); + $.isClaimedAtSnapshot[snapshotId][msg.sender][tokenList[i]] = true; + $.claimVaultAmount[tokenList[i]] -= claimableToken; + IERC20Upgradeable(tokenList[i]).safeTransfer(msg.sender, claimableToken); - emit RevenueTokenClaimed(msg.sender, tokens[i], claimableToken); + emit RevenueTokenClaimed(msg.sender, tokenList[i], claimableToken); } } @@ -246,19 +248,19 @@ contract IpRoyaltyVault is IIpRoyaltyVault, ERC20SnapshotUpgradeable, Reentrancy function _collectAccruedTokens(uint256 royaltyTokensToClaim, address ancestorIpId) internal { IpRoyaltyVaultStorage storage $ = _getIpRoyaltyVaultStorage(); - address[] memory tokens = $.tokens.values(); + address[] memory tokenList = $.tokens.values(); - for (uint256 i = 0; i < tokens.length; ++i) { + for (uint256 i = 0; i < tokenList.length; ++i) { // the only case in which unclaimedRoyaltyTokens can be 0 is when the vault is empty and everyone claimed // in which case the call will revert upstream with IpRoyaltyVault__AlreadyClaimed error - uint256 collectAmount = ($.ancestorsVaultAmount[tokens[i]] * royaltyTokensToClaim) / + uint256 collectAmount = ($.ancestorsVaultAmount[tokenList[i]] * royaltyTokensToClaim) / $.unclaimedRoyaltyTokens; if (collectAmount == 0) continue; - $.ancestorsVaultAmount[tokens[i]] -= collectAmount; - IERC20Upgradeable(tokens[i]).safeTransfer(ancestorIpId, collectAmount); + $.ancestorsVaultAmount[tokenList[i]] -= collectAmount; + IERC20Upgradeable(tokenList[i]).safeTransfer(ancestorIpId, collectAmount); - emit RevenueTokenClaimed(ancestorIpId, tokens[i], collectAmount); + emit RevenueTokenClaimed(ancestorIpId, tokenList[i], collectAmount); } } diff --git a/contracts/modules/royalty/policies/RoyaltyPolicyLAP.sol b/contracts/modules/royalty/policies/RoyaltyPolicyLAP.sol index 55cf17c3d..d07d50284 100644 --- a/contracts/modules/royalty/policies/RoyaltyPolicyLAP.sol +++ b/contracts/modules/royalty/policies/RoyaltyPolicyLAP.sol @@ -72,9 +72,10 @@ contract RoyaltyPolicyLAP is IRoyaltyPolicyLAP, AccessManagedUpgradeable, Reentr } /// @notice Initializer for this implementation contract - /// @param governance The governance address - function initialize(address governance) external initializer { - __AccessManaged_init(governance); + /// @param accessManager The address of the protocol admin roles contract + function initialize(address accessManager) external initializer { + if (accessManager == address(0)) revert Errors.RoyaltyPolicyLAP__ZeroAccessManager(); + __AccessManaged_init(accessManager); __ReentrancyGuard_init(); __UUPSUpgradeable_init(); } diff --git a/test/foundry/modules/royalty/RoyaltyModule.t.sol b/test/foundry/modules/royalty/RoyaltyModule.t.sol index 187bf9f54..b25ef85d5 100644 --- a/test/foundry/modules/royalty/RoyaltyModule.t.sol +++ b/test/foundry/modules/royalty/RoyaltyModule.t.sol @@ -23,22 +23,6 @@ contract TestRoyaltyModule is BaseTest { address internal ipAccount2 = address(0x111000bbb); address internal ipAddr; address internal arbitrationRelayer; - - struct InitParams { - address[] targetAncestors; - uint32[] targetRoyaltyAmount; - address[] parentAncestors1; - address[] parentAncestors2; - uint32[] parentAncestorsRoyalties1; - uint32[] parentAncestorsRoyalties2; - } - - InitParams internal initParamsMax; - bytes internal MAX_ANCESTORS; - address[] internal MAX_ANCESTORS_ = new address[](14); - uint32[] internal MAX_ANCESTORS_ROYALTY_ = new uint32[](14); - address[] internal parentsIpIds100; - RoyaltyPolicyLAP internal royaltyPolicyLAP2; function setUp() public override { @@ -105,55 +89,28 @@ contract TestRoyaltyModule is BaseTest { function _setupTree() internal { // init royalty policy for roots - address[] memory nullTargetAncestors = new address[](0); - uint32[] memory nullTargetRoyaltyAmount = new uint32[](0); - uint32[] memory parentRoyalties = new uint32[](0); - address[] memory nullParentAncestors1 = new address[](0); - address[] memory nullParentAncestors2 = new address[](0); - uint32[] memory nullParentAncestorsRoyalties1 = new uint32[](0); - uint32[] memory nullParentAncestorsRoyalties2 = new uint32[](0); - InitParams memory nullInitParams = InitParams({ - targetAncestors: nullTargetAncestors, - targetRoyaltyAmount: nullTargetRoyaltyAmount, - parentAncestors1: nullParentAncestors1, - parentAncestors2: nullParentAncestors2, - parentAncestorsRoyalties1: nullParentAncestorsRoyalties1, - parentAncestorsRoyalties2: nullParentAncestorsRoyalties2 - }); - bytes memory nullBytes = abi.encode(nullInitParams); - - royaltyModule.onLicenseMinting(address(7), address(royaltyPolicyLAP), abi.encode(uint32(7)), nullBytes); - royaltyModule.onLicenseMinting(address(8), address(royaltyPolicyLAP), abi.encode(uint32(8)), nullBytes); + royaltyModule.onLicenseMinting(address(7), address(royaltyPolicyLAP), abi.encode(uint32(7)), ""); + royaltyModule.onLicenseMinting(address(8), address(royaltyPolicyLAP), abi.encode(uint32(8)), ""); // init 2nd level with children address[] memory parents = new address[](2); - address[] memory targetAncestors1 = new address[](2); - uint32[] memory targetRoyaltyAmount1 = new uint32[](2); - uint32[] memory parentRoyalties1 = new uint32[](2); + uint32[] memory parentRoyalties = new uint32[](2); bytes[] memory encodedLicenseData = new bytes[](2); // 3 is child of 7 and 8 parents[0] = address(7); parents[1] = address(8); - parentRoyalties1[0] = 7; - parentRoyalties1[1] = 8; - targetAncestors1[0] = address(7); - targetAncestors1[1] = address(8); - targetRoyaltyAmount1[0] = 7; - targetRoyaltyAmount1[1] = 8; - InitParams memory initParams = InitParams({ - targetAncestors: targetAncestors1, - targetRoyaltyAmount: targetRoyaltyAmount1, - parentAncestors1: nullParentAncestors1, - parentAncestors2: nullParentAncestors2, - parentAncestorsRoyalties1: nullParentAncestorsRoyalties1, - parentAncestorsRoyalties2: nullParentAncestorsRoyalties2 - }); - for (uint32 i = 0; i < parentRoyalties1.length; i++) { - encodedLicenseData[i] = abi.encode(parentRoyalties1[i]); + parentRoyalties[0] = 7; + parentRoyalties[1] = 8; + for (uint32 i = 0; i < parentRoyalties.length; i++) { + encodedLicenseData[i] = abi.encode(parentRoyalties[i]); } - bytes memory encodedBytes = abi.encode(initParams); - royaltyModule.onLinkToParents(address(3), address(royaltyPolicyLAP), parents, encodedLicenseData, encodedBytes); + royaltyModule.onLinkToParents(address(3), address(royaltyPolicyLAP), parents, encodedLicenseData, ""); + } + function test_RoyaltyModule_initialize_revert_ZeroAccessManager() public { + address impl = address(new RoyaltyModule()); + vm.expectRevert(Errors.RoyaltyModule__ZeroAccessManager.selector); + RoyaltyModule(TestProxyHelper.deployUUPSProxy(impl, abi.encodeCall(RoyaltyModule.initialize, address(0)))); } function test_RoyaltyModule_setDisputeModule_revert_ZeroDisputeModule() public { @@ -264,41 +221,8 @@ contract TestRoyaltyModule is BaseTest { function test_RoyaltyModule_onLicenseMinting_Derivative() public { address licensor = address(3); bytes memory licenseData = abi.encode(uint32(15)); - - address[] memory parents = new address[](2); - address[] memory targetAncestors1 = new address[](2); - uint32[] memory targetRoyaltyAmount1 = new uint32[](2); - uint32[] memory parentRoyalties1 = new uint32[](2); - bytes[] memory encodedLicenseData = new bytes[](2); - - address[] memory nullParentAncestors1 = new address[](0); - address[] memory nullParentAncestors2 = new address[](0); - uint32[] memory nullParentAncestorsRoyalties1 = new uint32[](0); - uint32[] memory nullParentAncestorsRoyalties2 = new uint32[](0); - - parents[0] = address(7); - parents[1] = address(8); - parentRoyalties1[0] = 7; - parentRoyalties1[1] = 8; - targetAncestors1[0] = address(7); - targetAncestors1[1] = address(8); - targetRoyaltyAmount1[0] = 7; - targetRoyaltyAmount1[1] = 8; - InitParams memory initParams = InitParams({ - targetAncestors: targetAncestors1, - targetRoyaltyAmount: targetRoyaltyAmount1, - parentAncestors1: nullParentAncestors1, - parentAncestors2: nullParentAncestors2, - parentAncestorsRoyalties1: nullParentAncestorsRoyalties1, - parentAncestorsRoyalties2: nullParentAncestorsRoyalties2 - }); - for (uint32 i = 0; i < parentRoyalties1.length; i++) { - encodedLicenseData[i] = abi.encode(parentRoyalties1[i]); - } - bytes memory encodedBytes = abi.encode(initParams); - vm.startPrank(address(licensingModule)); - royaltyModule.onLicenseMinting(licensor, address(royaltyPolicyLAP), licenseData, encodedBytes); + royaltyModule.onLicenseMinting(licensor, address(royaltyPolicyLAP), licenseData, ""); } function test_RoyaltyModule_onLicenseMinting_Root() public { @@ -306,25 +230,8 @@ contract TestRoyaltyModule is BaseTest { bytes memory licenseData = abi.encode(uint32(15)); // mint a license of another policy - address[] memory nullTargetAncestors = new address[](0); - uint32[] memory nullTargetRoyaltyAmount = new uint32[](0); - uint32[] memory parentRoyalties = new uint32[](0); - address[] memory nullParentAncestors1 = new address[](0); - address[] memory nullParentAncestors2 = new address[](0); - uint32[] memory nullParentAncestorsRoyalties1 = new uint32[](0); - uint32[] memory nullParentAncestorsRoyalties2 = new uint32[](0); - InitParams memory nullInitParams = InitParams({ - targetAncestors: nullTargetAncestors, - targetRoyaltyAmount: nullTargetRoyaltyAmount, - parentAncestors1: nullParentAncestors1, - parentAncestors2: nullParentAncestors2, - parentAncestorsRoyalties1: nullParentAncestorsRoyalties1, - parentAncestorsRoyalties2: nullParentAncestorsRoyalties2 - }); - bytes memory nullBytes = abi.encode(nullInitParams); - vm.startPrank(address(licensingModule)); - royaltyModule.onLicenseMinting(licensor, address(royaltyPolicyLAP), licenseData, nullBytes); + royaltyModule.onLicenseMinting(licensor, address(royaltyPolicyLAP), licenseData, ""); vm.stopPrank(); vm.startPrank(u.admin); @@ -332,127 +239,58 @@ contract TestRoyaltyModule is BaseTest { vm.stopPrank(); vm.startPrank(address(licensingModule)); - royaltyModule.onLicenseMinting(licensor, address(royaltyPolicyLAP), licenseData, nullBytes); + royaltyModule.onLicenseMinting(licensor, address(royaltyPolicyLAP), licenseData, ""); } function test_RoyaltyModule_onLinkToParents_revert_NotWhitelistedRoyaltyPolicy() public { address newChild = address(9); address[] memory parents = new address[](2); - address[] memory targetAncestors1 = new address[](2); - uint32[] memory targetRoyaltyAmount1 = new uint32[](2); - uint32[] memory parentRoyalties1 = new uint32[](2); + uint32[] memory parentRoyalties = new uint32[](2); bytes[] memory encodedLicenseData = new bytes[](2); - address[] memory nullParentAncestors1 = new address[](0); - address[] memory nullParentAncestors2 = new address[](0); - uint32[] memory nullParentAncestorsRoyalties1 = new uint32[](0); - uint32[] memory nullParentAncestorsRoyalties2 = new uint32[](0); - parents[0] = address(7); parents[1] = address(8); - parentRoyalties1[0] = 7; - parentRoyalties1[1] = 8; - targetAncestors1[0] = address(7); - targetAncestors1[1] = address(8); - targetRoyaltyAmount1[0] = 7; - targetRoyaltyAmount1[1] = 8; - InitParams memory initParams = InitParams({ - targetAncestors: targetAncestors1, - targetRoyaltyAmount: targetRoyaltyAmount1, - parentAncestors1: nullParentAncestors1, - parentAncestors2: nullParentAncestors2, - parentAncestorsRoyalties1: nullParentAncestorsRoyalties1, - parentAncestorsRoyalties2: nullParentAncestorsRoyalties2 - }); - for (uint32 i = 0; i < parentRoyalties1.length; i++) { - encodedLicenseData[i] = abi.encode(parentRoyalties1[i]); + parentRoyalties[0] = 7; + parentRoyalties[1] = 8; + for (uint32 i = 0; i < parentRoyalties.length; i++) { + encodedLicenseData[i] = abi.encode(parentRoyalties[i]); } - bytes memory encodedBytes = abi.encode(initParams); - vm.startPrank(address(licensingModule)); vm.expectRevert(Errors.RoyaltyModule__NotWhitelistedRoyaltyPolicy.selector); - royaltyModule.onLinkToParents(newChild, address(1), parents, encodedLicenseData, encodedBytes); + royaltyModule.onLinkToParents(newChild, address(1), parents, encodedLicenseData, ""); } function test_RoyaltyModule_onLinkToParents_revert_NoParentsOnLinking() public { address newChild = address(9); address[] memory parents = new address[](0); - address[] memory targetAncestors1 = new address[](2); - uint32[] memory targetRoyaltyAmount1 = new uint32[](2); - uint32[] memory parentRoyalties1 = new uint32[](2); + uint32[] memory parentRoyalties = new uint32[](2); bytes[] memory encodedLicenseData = new bytes[](2); - address[] memory nullParentAncestors1 = new address[](0); - address[] memory nullParentAncestors2 = new address[](0); - uint32[] memory nullParentAncestorsRoyalties1 = new uint32[](0); - uint32[] memory nullParentAncestorsRoyalties2 = new uint32[](0); - - parentRoyalties1[0] = 7; - parentRoyalties1[1] = 8; - targetAncestors1[0] = address(7); - targetAncestors1[1] = address(8); - targetRoyaltyAmount1[0] = 7; - targetRoyaltyAmount1[1] = 8; - InitParams memory initParams = InitParams({ - targetAncestors: targetAncestors1, - targetRoyaltyAmount: targetRoyaltyAmount1, - parentAncestors1: nullParentAncestors1, - parentAncestors2: nullParentAncestors2, - parentAncestorsRoyalties1: nullParentAncestorsRoyalties1, - parentAncestorsRoyalties2: nullParentAncestorsRoyalties2 - }); - for (uint32 i = 0; i < parentRoyalties1.length; i++) { - encodedLicenseData[i] = abi.encode(parentRoyalties1[i]); + parentRoyalties[0] = 7; + parentRoyalties[1] = 8; + for (uint32 i = 0; i < parentRoyalties.length; i++) { + encodedLicenseData[i] = abi.encode(parentRoyalties[i]); } - bytes memory encodedBytes = abi.encode(initParams); - vm.startPrank(address(licensingModule)); vm.expectRevert(Errors.RoyaltyModule__NoParentsOnLinking.selector); - royaltyModule.onLinkToParents(newChild, address(royaltyPolicyLAP), parents, encodedLicenseData, encodedBytes); + royaltyModule.onLinkToParents(newChild, address(royaltyPolicyLAP), parents, encodedLicenseData, ""); } function test_RoyaltyModule_onLinkToParents_revert_IncompatibleRoyaltyPolicy() public { address newChild = address(9); address[] memory parents = new address[](2); - address[] memory targetAncestors1 = new address[](3); - uint32[] memory targetRoyaltyAmount1 = new uint32[](3); - uint32[] memory parentRoyalties1 = new uint32[](1); + uint32[] memory parentRoyalties = new uint32[](1); bytes[] memory encodedLicenseData = new bytes[](2); - address[] memory ParentAncestors1 = new address[](2); - address[] memory nullParentAncestors2 = new address[](0); - uint32[] memory ParentAncestorsRoyalties1 = new uint32[](2); - uint32[] memory nullParentAncestorsRoyalties2 = new uint32[](0); - parents[0] = address(3); - parentRoyalties1[0] = 3; - targetAncestors1[0] = address(3); - targetAncestors1[1] = address(7); - targetAncestors1[2] = address(8); - targetRoyaltyAmount1[0] = 3; - targetRoyaltyAmount1[1] = 7; - targetRoyaltyAmount1[2] = 8; - ParentAncestors1[0] = address(7); - ParentAncestors1[1] = address(8); - ParentAncestorsRoyalties1[0] = 7; - ParentAncestorsRoyalties1[1] = 8; - InitParams memory initParams = InitParams({ - targetAncestors: targetAncestors1, - targetRoyaltyAmount: targetRoyaltyAmount1, - parentAncestors1: ParentAncestors1, - parentAncestors2: nullParentAncestors2, - parentAncestorsRoyalties1: ParentAncestorsRoyalties1, - parentAncestorsRoyalties2: nullParentAncestorsRoyalties2 - }); - for (uint32 i = 0; i < parentRoyalties1.length; i++) { - encodedLicenseData[i] = abi.encode(parentRoyalties1[i]); + parentRoyalties[0] = 3; + for (uint32 i = 0; i < parentRoyalties.length; i++) { + encodedLicenseData[i] = abi.encode(parentRoyalties[i]); } - bytes memory encodedBytes = abi.encode(initParams); - vm.startPrank(u.admin); royaltyModule.whitelistRoyaltyPolicy(address(royaltyPolicyLAP2), true); vm.stopPrank(); vm.startPrank(address(licensingModule)); vm.expectRevert(Errors.RoyaltyModule__IncompatibleRoyaltyPolicy.selector); - royaltyModule.onLinkToParents(newChild, address(royaltyPolicyLAP2), parents, encodedLicenseData, encodedBytes); + royaltyModule.onLinkToParents(newChild, address(royaltyPolicyLAP2), parents, encodedLicenseData, ""); } function test_RoyaltyModule_onLinkToParents() public { @@ -460,38 +298,17 @@ contract TestRoyaltyModule is BaseTest { // new child is linked to 7 and 8 address[] memory parents = new address[](2); - address[] memory targetAncestors1 = new address[](2); - uint32[] memory targetRoyaltyAmount1 = new uint32[](2); - uint32[] memory parentRoyalties1 = new uint32[](2); + uint32[] memory parentRoyalties = new uint32[](2); bytes[] memory encodedLicenseData = new bytes[](2); - address[] memory nullParentAncestors1 = new address[](0); - address[] memory nullParentAncestors2 = new address[](0); - uint32[] memory nullParentAncestorsRoyalties1 = new uint32[](0); - uint32[] memory nullParentAncestorsRoyalties2 = new uint32[](0); - parents[0] = address(7); parents[1] = address(8); - parentRoyalties1[0] = 7; - parentRoyalties1[1] = 8; - targetAncestors1[0] = address(7); - targetAncestors1[1] = address(8); - targetRoyaltyAmount1[0] = 7; - targetRoyaltyAmount1[1] = 8; - InitParams memory initParams = InitParams({ - targetAncestors: targetAncestors1, - targetRoyaltyAmount: targetRoyaltyAmount1, - parentAncestors1: nullParentAncestors1, - parentAncestors2: nullParentAncestors2, - parentAncestorsRoyalties1: nullParentAncestorsRoyalties1, - parentAncestorsRoyalties2: nullParentAncestorsRoyalties2 - }); - for (uint32 i = 0; i < parentRoyalties1.length; i++) { - encodedLicenseData[i] = abi.encode(parentRoyalties1[i]); + parentRoyalties[0] = 7; + parentRoyalties[1] = 8; + for (uint32 i = 0; i < parentRoyalties.length; i++) { + encodedLicenseData[i] = abi.encode(parentRoyalties[i]); } - bytes memory encodedBytes = abi.encode(initParams); - vm.startPrank(address(licensingModule)); - royaltyModule.onLinkToParents(newChild, address(royaltyPolicyLAP), parents, encodedLicenseData, encodedBytes); + royaltyModule.onLinkToParents(newChild, address(royaltyPolicyLAP), parents, encodedLicenseData, ""); assertEq(royaltyModule.royaltyPolicies(newChild), address(royaltyPolicyLAP)); } @@ -583,7 +400,28 @@ contract TestRoyaltyModule is BaseTest { vm.expectRevert(Errors.RoyaltyModule__IpIsTagged.selector); royaltyModule.payLicenseMintingFee(ipAddr, ipAccount1, address(royaltyPolicyLAP), address(USDC), 100); } - + function test_RoyaltyModule_payLicenseMintingFee_revert_NotWhitelistedRoyaltyToken() public { + uint256 royaltyAmount = 100 * 10 ** 6; + address receiverIpId = address(7); + address payerAddress = address(3); + address licenseRoyaltyPolicy = address(royaltyPolicyLAP); + address token = address(1); + vm.startPrank(address(licensingModule)); + vm.expectRevert(Errors.RoyaltyModule__NotWhitelistedRoyaltyToken.selector); + royaltyModule.payLicenseMintingFee(receiverIpId, payerAddress, licenseRoyaltyPolicy, token, royaltyAmount); + } + function test_RoyaltyModule_payLicenseMintingFee_revert_NotWhitelistedRoyaltyPolicy() public { + uint256 royaltyAmount = 100 * 10 ** 6; + address receiverIpId = address(7); + address payerAddress = address(3); + address licenseRoyaltyPolicy = address(1); + address token = address(USDC); + vm.startPrank(u.admin); + royaltyModule.whitelistRoyaltyPolicy(address(royaltyPolicyLAP), false); + vm.startPrank(address(licensingModule)); + vm.expectRevert(Errors.RoyaltyModule__NotWhitelistedRoyaltyPolicy.selector); + royaltyModule.payLicenseMintingFee(receiverIpId, payerAddress, licenseRoyaltyPolicy, token, royaltyAmount); + } function test_RoyaltyModule_payLicenseMintingFee() public { uint256 royaltyAmount = 100 * 10 ** 6; address receiverIpId = address(7); diff --git a/test/foundry/modules/royalty/RoyaltyPolicyLAP.t.sol b/test/foundry/modules/royalty/RoyaltyPolicyLAP.t.sol index be4fb574c..d3a4d7594 100644 --- a/test/foundry/modules/royalty/RoyaltyPolicyLAP.t.sol +++ b/test/foundry/modules/royalty/RoyaltyPolicyLAP.t.sol @@ -40,50 +40,50 @@ contract TestRoyaltyPolicyLAP is BaseTest { // init 2nd level with children address[] memory parents = new address[](2); - uint32[] memory parentRoyalties1 = new uint32[](2); + uint32[] memory parentRoyalties = new uint32[](2); bytes[] memory encodedLicenseData = new bytes[](2); // 3 is child of 7 and 8 parents[0] = address(7); parents[1] = address(8); - parentRoyalties1[0] = 7; - parentRoyalties1[1] = 8; + parentRoyalties[0] = 7; + parentRoyalties[1] = 8; - for (uint32 i = 0; i < parentRoyalties1.length; i++) { - encodedLicenseData[i] = abi.encode(parentRoyalties1[i]); + for (uint32 i = 0; i < parentRoyalties.length; i++) { + encodedLicenseData[i] = abi.encode(parentRoyalties[i]); } royaltyPolicyLAP.onLinkToParents(address(3), parents, encodedLicenseData, ""); // 4 is child of 9 and 10 parents[0] = address(9); parents[1] = address(10); - parentRoyalties1[0] = 9; - parentRoyalties1[1] = 10; + parentRoyalties[0] = 9; + parentRoyalties[1] = 10; - for (uint32 i = 0; i < parentRoyalties1.length; i++) { - encodedLicenseData[i] = abi.encode(parentRoyalties1[i]); + for (uint32 i = 0; i < parentRoyalties.length; i++) { + encodedLicenseData[i] = abi.encode(parentRoyalties[i]); } royaltyPolicyLAP.onLinkToParents(address(4), parents, encodedLicenseData, ""); // 5 is child of 11 and 12 parents[0] = address(11); parents[1] = address(12); - parentRoyalties1[0] = 11; - parentRoyalties1[1] = 12; + parentRoyalties[0] = 11; + parentRoyalties[1] = 12; - for (uint32 i = 0; i < parentRoyalties1.length; i++) { - encodedLicenseData[i] = abi.encode(parentRoyalties1[i]); + for (uint32 i = 0; i < parentRoyalties.length; i++) { + encodedLicenseData[i] = abi.encode(parentRoyalties[i]); } royaltyPolicyLAP.onLinkToParents(address(5), parents, encodedLicenseData, ""); // 6 is child of 13 and 14 parents[0] = address(13); parents[1] = address(14); - parentRoyalties1[0] = 13; - parentRoyalties1[1] = 14; + parentRoyalties[0] = 13; + parentRoyalties[1] = 14; - for (uint32 i = 0; i < parentRoyalties1.length; i++) { - encodedLicenseData[i] = abi.encode(parentRoyalties1[i]); + for (uint32 i = 0; i < parentRoyalties.length; i++) { + encodedLicenseData[i] = abi.encode(parentRoyalties[i]); } royaltyPolicyLAP.onLinkToParents(address(6), parents, encodedLicenseData, ""); @@ -91,22 +91,22 @@ contract TestRoyaltyPolicyLAP is BaseTest { // 1 is child of 3 and 4 parents[0] = address(3); parents[1] = address(4); - parentRoyalties1[0] = 3; - parentRoyalties1[1] = 4; + parentRoyalties[0] = 3; + parentRoyalties[1] = 4; - for (uint32 i = 0; i < parentRoyalties1.length; i++) { - encodedLicenseData[i] = abi.encode(parentRoyalties1[i]); + for (uint32 i = 0; i < parentRoyalties.length; i++) { + encodedLicenseData[i] = abi.encode(parentRoyalties[i]); } royaltyPolicyLAP.onLinkToParents(address(1), parents, encodedLicenseData, ""); // 2 is child of 5 and 6 parents[0] = address(5); parents[1] = address(6); - parentRoyalties1[0] = 5; - parentRoyalties1[1] = 6; + parentRoyalties[0] = 5; + parentRoyalties[1] = 6; - for (uint32 i = 0; i < parentRoyalties1.length; i++) { - encodedLicenseData[i] = abi.encode(parentRoyalties1[i]); + for (uint32 i = 0; i < parentRoyalties.length; i++) { + encodedLicenseData[i] = abi.encode(parentRoyalties[i]); } royaltyPolicyLAP.onLinkToParents(address(2), parents, encodedLicenseData, ""); From a2a189032de54636a0fd88ca3d2276eb31ecfc75 Mon Sep 17 00:00:00 2001 From: Spablob Date: Sat, 13 Apr 2024 00:35:38 +0300 Subject: [PATCH 2/3] add the removed restriction back --- contracts/modules/royalty/policies/IpRoyaltyVault.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contracts/modules/royalty/policies/IpRoyaltyVault.sol b/contracts/modules/royalty/policies/IpRoyaltyVault.sol index 921a64b75..15b2c6d74 100644 --- a/contracts/modules/royalty/policies/IpRoyaltyVault.sol +++ b/contracts/modules/royalty/policies/IpRoyaltyVault.sol @@ -86,6 +86,8 @@ contract IpRoyaltyVault is IIpRoyaltyVault, ERC20SnapshotUpgradeable, Reentrancy uint32 unclaimedTokens, address ipIdAddress ) external initializer { + if (ipIdAddress == address(0)) revert Errors.IpRoyaltyVault__ZeroIpId(); + IpRoyaltyVaultStorage storage $ = _getIpRoyaltyVaultStorage(); $.ipId = ipIdAddress; From 9e28aac801fb35a0b70f3b668a40599dd757daae Mon Sep 17 00:00:00 2001 From: Spablob Date: Sat, 13 Apr 2024 00:36:16 +0300 Subject: [PATCH 3/3] format fix --- contracts/modules/royalty/policies/IpRoyaltyVault.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/modules/royalty/policies/IpRoyaltyVault.sol b/contracts/modules/royalty/policies/IpRoyaltyVault.sol index 15b2c6d74..b48555ca0 100644 --- a/contracts/modules/royalty/policies/IpRoyaltyVault.sol +++ b/contracts/modules/royalty/policies/IpRoyaltyVault.sol @@ -87,7 +87,7 @@ contract IpRoyaltyVault is IIpRoyaltyVault, ERC20SnapshotUpgradeable, Reentrancy address ipIdAddress ) external initializer { if (ipIdAddress == address(0)) revert Errors.IpRoyaltyVault__ZeroIpId(); - + IpRoyaltyVaultStorage storage $ = _getIpRoyaltyVaultStorage(); $.ipId = ipIdAddress;