1
1
// SPDX-License-Identifier: MIT
2
2
pragma solidity 0.8.26 ;
3
3
4
+ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol " ;
5
+ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol " ;
4
6
import { Errors as CoreErrors } from "@storyprotocol/core/lib/Errors.sol " ;
7
+ import { ILicenseTemplate } from "@storyprotocol/core/interfaces/modules/licensing/ILicenseTemplate.sol " ;
5
8
import { ILicensingModule } from "@storyprotocol/core/interfaces/modules/licensing/ILicensingModule.sol " ;
6
9
import { IPILicenseTemplate, PILTerms } from "@storyprotocol/core/interfaces/modules/licensing/IPILicenseTemplate.sol " ;
7
10
8
11
/// @title Periphery Licensing Helper Library
9
12
/// @notice Library for all licensing related helper functions for Periphery contracts.
10
13
library LicensingHelper {
11
- /// @dev Registers PIL License Terms and attaches them to the given IP.
14
+ using SafeERC20 for IERC20 ;
15
+
16
+ /// @dev Registers multiple PIL License Terms and attaches them to the given IP.
12
17
/// @param ipId The ID of the IP.
13
18
/// @param pilTemplate The address of the PIL License Template.
14
19
/// @param licensingModule The address of the Licensing Module.
@@ -24,11 +29,34 @@ library LicensingHelper {
24
29
) internal returns (uint256 [] memory licenseTermsIds ) {
25
30
licenseTermsIds = new uint256 [](terms.length );
26
31
for (uint256 i = 0 ; i < terms.length ; i++ ) {
27
- licenseTermsIds[i] = IPILicenseTemplate (pilTemplate).registerLicenseTerms (terms[i]);
28
- attachLicenseTerms (ipId, licensingModule, licenseRegistry, pilTemplate, licenseTermsIds[i]);
32
+ licenseTermsIds[i] = registerPILTermsAndAttach (
33
+ ipId,
34
+ pilTemplate,
35
+ licensingModule,
36
+ licenseRegistry,
37
+ terms[i]
38
+ );
29
39
}
30
40
}
31
41
42
+ /// @dev Registers a single PIL License and attaches it to the given IP.
43
+ /// @param ipId The ID of the IP.
44
+ /// @param pilTemplate The address of the PIL License Template.
45
+ /// @param licensingModule The address of the Licensing Module.
46
+ /// @param licenseRegistry The address of the License Registry.
47
+ /// @param terms The PIL terms to be registered.
48
+ /// @return licenseTermsId The ID of the registered PIL terms.
49
+ function registerPILTermsAndAttach (
50
+ address ipId ,
51
+ address pilTemplate ,
52
+ address licensingModule ,
53
+ address licenseRegistry ,
54
+ PILTerms calldata terms
55
+ ) internal returns (uint256 licenseTermsId ) {
56
+ licenseTermsId = IPILicenseTemplate (pilTemplate).registerLicenseTerms (terms);
57
+ attachLicenseTerms (ipId, licensingModule, licenseRegistry, pilTemplate, licenseTermsId);
58
+ }
59
+
32
60
/// @dev Attaches license terms to the given IP.
33
61
/// @param ipId The ID of the IP.
34
62
/// @param licensingModule The address of the Licensing Module.
@@ -53,4 +81,71 @@ library LicensingHelper {
53
81
}
54
82
}
55
83
}
84
+
85
+ /// @dev Collect mint fees for all parent IPs from the payer and set approval for Royalty Module to spend mint fees.
86
+ /// @param payerAddress The address of the payer for the license mint fees.
87
+ /// @param royaltyModule The address of the Royalty Module.
88
+ /// @param licensingModule The address of the Licensing Module.
89
+ /// @param licenseTemplate The address of the license template.
90
+ /// @param parentIpIds The IDs of all the parent IPs.
91
+ /// @param licenseTermsIds The IDs of the license terms for each corresponding parent IP.
92
+ function collectMintFeesAndSetApproval (
93
+ address payerAddress ,
94
+ address royaltyModule ,
95
+ address licensingModule ,
96
+ address licenseTemplate ,
97
+ address [] memory parentIpIds ,
98
+ uint256 [] memory licenseTermsIds
99
+ ) internal {
100
+ ILicenseTemplate lct = ILicenseTemplate (licenseTemplate);
101
+ (address royaltyPolicy , , , address mintFeeCurrencyToken ) = lct.getRoyaltyPolicy (licenseTermsIds[0 ]);
102
+
103
+ if (royaltyPolicy != address (0 )) {
104
+ // Get total mint fee for all parent IPs
105
+ uint256 totalMintFee = aggregateMintFees ({
106
+ payerAddress: payerAddress,
107
+ licensingModule: licensingModule,
108
+ licenseTemplate: licenseTemplate,
109
+ parentIpIds: parentIpIds,
110
+ licenseTermsIds: licenseTermsIds
111
+ });
112
+
113
+ if (totalMintFee != 0 ) {
114
+ // Transfer mint fee from payer to this contract
115
+ IERC20 (mintFeeCurrencyToken).safeTransferFrom (payerAddress, address (this ), totalMintFee);
116
+
117
+ // Approve Royalty Policy to spend mint fee
118
+ IERC20 (mintFeeCurrencyToken).forceApprove (royaltyModule, totalMintFee);
119
+ }
120
+ }
121
+ }
122
+
123
+ /// @dev Aggregate license mint fees for all parent IPs.
124
+ /// @param payerAddress The address of the payer for the license mint fees.
125
+ /// @param licensingModule The address of the Licensing Module.
126
+ /// @param licenseTemplate The address of the license template.
127
+ /// @param parentIpIds The IDs of all the parent IPs.
128
+ /// @param licenseTermsIds The IDs of the license terms for each corresponding parent IP.
129
+ /// @return totalMintFee The sum of license mint fees across all parent IPs.
130
+ function aggregateMintFees (
131
+ address payerAddress ,
132
+ address licensingModule ,
133
+ address licenseTemplate ,
134
+ address [] memory parentIpIds ,
135
+ uint256 [] memory licenseTermsIds
136
+ ) internal view returns (uint256 totalMintFee ) {
137
+ uint256 mintFee;
138
+
139
+ for (uint256 i = 0 ; i < parentIpIds.length ; i++ ) {
140
+ (, mintFee) = ILicensingModule (licensingModule).predictMintingLicenseFee ({
141
+ licensorIpId: parentIpIds[i],
142
+ licenseTemplate: licenseTemplate,
143
+ licenseTermsId: licenseTermsIds[i],
144
+ amount: 1 ,
145
+ receiver: payerAddress,
146
+ royaltyContext: ""
147
+ });
148
+ totalMintFee += mintFee;
149
+ }
150
+ }
56
151
}
0 commit comments