Skip to content

Commit 0c34d1b

Browse files
committed
feat(royalty): add enhancements to RoyaltyWorkflows
1 parent 6ce2557 commit 0c34d1b

File tree

3 files changed

+147
-33
lines changed

3 files changed

+147
-33
lines changed

contracts/RoyaltyWorkflows.sol

+55-10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC16
77
import { MulticallUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol";
88
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
99

10+
import { Errors as CoreErrors } from "@storyprotocol/core/lib/Errors.sol";
1011
// solhint-disable-next-line max-line-length
1112
import { IGraphAwareRoyaltyPolicy } from "@storyprotocol/core/interfaces/modules/royalty/policies/IGraphAwareRoyaltyPolicy.sol";
1213
import { IIpRoyaltyVault } from "@storyprotocol/core/interfaces/modules/royalty/policies/IIpRoyaltyVault.sol";
@@ -45,15 +46,13 @@ contract RoyaltyWorkflows is IRoyaltyWorkflows, MulticallUpgradeable, AccessMana
4546
/// and claims revenue on that snapshot for each specified currency token.
4647
/// @param ancestorIpId The address of the ancestor IP.
4748
/// @param claimer The address of the claimer of the revenue tokens (must be a royalty token holder).
48-
/// @param currencyTokens The addresses of the currency (revenue) tokens to claim (each address must be unique).
4949
/// @param royaltyClaimDetails The details of the royalty claim from child IPs,
5050
/// see {IRoyaltyWorkflows-RoyaltyClaimDetails}.
5151
/// @return snapshotId The ID of the snapshot taken.
5252
/// @return amountsClaimed The amount of revenue claimed for each currency token.
5353
function transferToVaultAndSnapshotAndClaimByTokenBatch(
5454
address ancestorIpId,
5555
address claimer,
56-
address[] calldata currencyTokens,
5756
RoyaltyClaimDetails[] calldata royaltyClaimDetails
5857
) external returns (uint256 snapshotId, uint256[] memory amountsClaimed) {
5958
// Transfers to ancestor's vault an amount of revenue tokens claimable via the given royalty policy
@@ -75,7 +74,7 @@ contract RoyaltyWorkflows is IRoyaltyWorkflows, MulticallUpgradeable, AccessMana
7574
// Claims revenue for each specified currency token from the latest snapshot
7675
amountsClaimed = ancestorIpRoyaltyVault.claimRevenueOnBehalfByTokenBatch({
7776
snapshotId: snapshotId,
78-
tokenList: currencyTokens,
77+
tokenList: _getCurrencyTokenList(royaltyClaimDetails),
7978
claimer: claimer
8079
});
8180
}
@@ -84,7 +83,6 @@ contract RoyaltyWorkflows is IRoyaltyWorkflows, MulticallUpgradeable, AccessMana
8483
/// specified currency token both on the new snapshot and on each specified unclaimed snapshots.
8584
/// @param ancestorIpId The address of the ancestor IP.
8685
/// @param claimer The address of the claimer of the revenue tokens (must be a royalty token holder).
87-
/// @param currencyTokens The addresses of the currency (revenue) tokens to claim (each address must be unique).
8886
/// @param unclaimedSnapshotIds The IDs of unclaimed snapshots to include in the claim.
8987
/// @param royaltyClaimDetails The details of the royalty claim from child IPs,
9088
/// see {IRoyaltyWorkflows-RoyaltyClaimDetails}.
@@ -93,7 +91,6 @@ contract RoyaltyWorkflows is IRoyaltyWorkflows, MulticallUpgradeable, AccessMana
9391
function transferToVaultAndSnapshotAndClaimBySnapshotBatch(
9492
address ancestorIpId,
9593
address claimer,
96-
address[] calldata currencyTokens,
9794
uint256[] calldata unclaimedSnapshotIds,
9895
RoyaltyClaimDetails[] calldata royaltyClaimDetails
9996
) external returns (uint256 snapshotId, uint256[] memory amountsClaimed) {
@@ -113,6 +110,8 @@ contract RoyaltyWorkflows is IRoyaltyWorkflows, MulticallUpgradeable, AccessMana
113110
// Takes a snapshot of the ancestor IP's royalty vault
114111
snapshotId = ancestorIpRoyaltyVault.snapshot();
115112

113+
address[] memory currencyTokens = _getCurrencyTokenList(royaltyClaimDetails);
114+
116115
// Claims revenue for each specified currency token from the latest snapshot
117116
amountsClaimed = ancestorIpRoyaltyVault.claimRevenueOnBehalfByTokenBatch({
118117
snapshotId: snapshotId,
@@ -130,8 +129,13 @@ contract RoyaltyWorkflows is IRoyaltyWorkflows, MulticallUpgradeable, AccessMana
130129
})
131130
returns (uint256 claimedAmount) {
132131
amountsClaimed[i] += claimedAmount;
133-
} catch {
134-
amountsClaimed[i] += 0;
132+
} catch (bytes memory reason) {
133+
// If the error is not IpRoyaltyVault__NoClaimableTokens, revert with the original error
134+
if (CoreErrors.IpRoyaltyVault__NoClaimableTokens.selector != bytes4(reason)) {
135+
assembly {
136+
revert(add(reason, 32), mload(reason))
137+
}
138+
}
135139
}
136140
}
137141
}
@@ -195,13 +199,54 @@ contract RoyaltyWorkflows is IRoyaltyWorkflows, MulticallUpgradeable, AccessMana
195199
})
196200
returns (uint256 claimedAmount) {
197201
amountsClaimed[i] += claimedAmount;
198-
} catch {
199-
// Continue to the next currency token
200-
amountsClaimed[i] += 0;
202+
} catch (bytes memory reason) {
203+
// If the error is not IpRoyaltyVault__NoClaimableTokens, revert with the original error
204+
if (CoreErrors.IpRoyaltyVault__NoClaimableTokens.selector != bytes4(reason)) {
205+
assembly {
206+
revert(add(reason, 32), mload(reason))
207+
}
208+
}
201209
}
202210
}
203211
}
204212

213+
/// @dev Extracts all unique currency token addresses from an array of RoyaltyClaimDetails.
214+
/// @param royaltyClaimDetails The details of the royalty claim from child IPs,
215+
/// see {IRoyaltyWorkflows-RoyaltyClaimDetails}.
216+
/// @return currencyTokenList An array of unique currency token addresses extracted from `royaltyClaimDetails`.
217+
function _getCurrencyTokenList(
218+
RoyaltyClaimDetails[] calldata royaltyClaimDetails
219+
) private pure returns (address[] memory currencyTokenList) {
220+
uint256 length = royaltyClaimDetails.length;
221+
address[] memory tempUniqueTokenList = new address[](length);
222+
uint256 uniqueCount = 0;
223+
224+
for (uint256 i = 0; i < length; i++) {
225+
address currencyToken = royaltyClaimDetails[i].currencyToken;
226+
bool isDuplicate = false;
227+
228+
// Check if `currencyToken` already in `tempUniqueTokenList`
229+
for (uint256 j = 0; j < uniqueCount; j++) {
230+
if (tempUniqueTokenList[j] == currencyToken) {
231+
// set the `isDuplicate` flag if `currencyToken` already in `tempUniqueTokenList`
232+
isDuplicate = true;
233+
break;
234+
}
235+
}
236+
237+
// Add `currencyToken` to `tempUniqueTokenList` if it's not already in `tempUniqueTokenList`
238+
if (!isDuplicate) {
239+
tempUniqueTokenList[uniqueCount] = currencyToken;
240+
uniqueCount++;
241+
}
242+
}
243+
244+
currencyTokenList = new address[](uniqueCount);
245+
for (uint256 i = 0; i < uniqueCount; i++) {
246+
currencyTokenList[i] = tempUniqueTokenList[i];
247+
}
248+
}
249+
205250
//
206251
// Upgrade
207252
//

contracts/interfaces/IRoyaltyWorkflows.sol

-4
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,20 @@ interface IRoyaltyWorkflows {
2020
/// and claims revenue on that snapshot for each specified currency token.
2121
/// @param ancestorIpId The address of the ancestor IP.
2222
/// @param claimer The address of the claimer of the revenue tokens (must be a royalty token holder).
23-
/// @param currencyTokens The addresses of the currency (revenue) tokens to claim (each address must be unique).
2423
/// @param royaltyClaimDetails The details of the royalty claim from child IPs,
2524
/// see {IRoyaltyWorkflows-RoyaltyClaimDetails}.
2625
/// @return snapshotId The ID of the snapshot taken.
2726
/// @return amountsClaimed The amount of revenue claimed for each currency token.
2827
function transferToVaultAndSnapshotAndClaimByTokenBatch(
2928
address ancestorIpId,
3029
address claimer,
31-
address[] calldata currencyTokens,
3230
RoyaltyClaimDetails[] calldata royaltyClaimDetails
3331
) external returns (uint256 snapshotId, uint256[] memory amountsClaimed);
3432

3533
/// @notice Transfers royalties to the ancestor IP's royalty vault, takes a snapshot, claims revenue for each
3634
/// specified currency token both on the new snapshot and on each specified unclaimed snapshots.
3735
/// @param ancestorIpId The address of the ancestor IP.
3836
/// @param claimer The address of the claimer of the revenue tokens (must be a royalty token holder).
39-
/// @param currencyTokens The addresses of the currency (revenue) tokens to claim (each address must be unique).
4037
/// @param unclaimedSnapshotIds The IDs of unclaimed snapshots to include in the claim.
4138
/// @param royaltyClaimDetails The details of the royalty claim from child IPs,
4239
/// see {IRoyaltyWorkflows-RoyaltyClaimDetails}.
@@ -45,7 +42,6 @@ interface IRoyaltyWorkflows {
4542
function transferToVaultAndSnapshotAndClaimBySnapshotBatch(
4643
address ancestorIpId,
4744
address claimer,
48-
address[] calldata currencyTokens,
4945
uint256[] calldata unclaimedSnapshotIds,
5046
RoyaltyClaimDetails[] calldata royaltyClaimDetails
5147
) external returns (uint256 snapshotId, uint256[] memory amountsClaimed);

0 commit comments

Comments
 (0)