Skip to content

Commit

Permalink
Optimize claiming (storyprotocol#215)
Browse files Browse the repository at this point in the history
* add event to minting and linking on RoyaltyModule.sol
* LAP and LRP draft interface changes
  • Loading branch information
Spablob authored Sep 13, 2024
1 parent 1d28bf8 commit 73f655e
Show file tree
Hide file tree
Showing 27 changed files with 1,139 additions and 836 deletions.
2 changes: 1 addition & 1 deletion .solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"extends": "solhint:recommended",
"plugins": ["prettier"],
"rules": {
"code-complexity": ["error", 8],
"code-complexity": ["error", 9],
"compiler-version": ["error", ">=0.8.23"],
"const-name-snakecase": "off",
"no-empty-blocks": "off",
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ format:
# generate html report from lcov.info (ignore "line ... has branchcov but no linecov data" error)
coverage:
mkdir -p coverage
forge coverage --report lcov
forge coverage --report lcov --no-match-path "test/foundry/invariants/*"
lcov --remove lcov.info -o coverage/lcov.info 'test/*' 'script/*' --rc lcov_branch_coverage=1
genhtml coverage/lcov.info -o coverage --rc lcov_branch_coverage=1

Expand Down
43 changes: 41 additions & 2 deletions contracts/interfaces/modules/royalty/IRoyaltyModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,27 @@ interface IRoyaltyModule is IModule {
/// @param accumulatedRoyaltyPoliciesLimit The maximum number of accumulated royalty policies an IP asset can have
event IpGraphLimitsUpdated(uint256 maxParents, uint256 maxAncestors, uint256 accumulatedRoyaltyPoliciesLimit);

/// @notice Event emitted when a license is minted
/// @param ipId The ipId whose license is being minted (licensor)
/// @param royaltyPolicy The royalty policy address of the license being minted
/// @param licensePercent The license percentage of the license being minted
/// @param externalData The external data custom to the royalty policy being minted
event LicensedWithRoyalty(address ipId, address royaltyPolicy, uint32 licensePercent, bytes externalData);

/// @notice Event emitted when an IP asset is linked to parents
/// @param ipId The children ipId that is being linked to parents
/// @param parentIpIds The parent ipIds that the children ipId is being linked to
/// @param licenseRoyaltyPolicies The royalty policies of the each parent license being used to link
/// @param licensesPercent The license percentage of the licenses of each parent being used to link
/// @param externalData The external data custom to each the royalty policy being used to link
event LinkedToParents(
address ipId,
address[] parentIpIds,
address[] licenseRoyaltyPolicies,
uint32[] licensesPercent,
bytes externalData
);

/// @notice Sets the ip graph limits
/// @dev Enforced to be only callable by the protocol admin
/// @param parentLimit The maximum number of parents an IP asset can have
Expand Down Expand Up @@ -108,8 +129,17 @@ interface IRoyaltyModule is IModule {
/// @param amount The amount to pay
function payLicenseMintingFee(address receiverIpId, address payerAddress, address token, uint256 amount) external;

/// @notice Returns the total number of royalty tokens
function totalRtSupply() external pure returns (uint32);
/// @notice Returns the number of ancestors for a given IP asset
/// @param ipId The ID of IP asset
function getAncestorsCount(address ipId) external returns (uint256);

/// @notice Indicates if an IP asset has a specific ancestor IP asset
/// @param ipId The ID of IP asset
/// @param ancestorIpId The ID of the ancestor IP asset
function hasAncestorIp(address ipId, address ancestorIpId) external returns (bool);

/// @notice Returns the maximum percentage - represents 100%
function maxPercent() external pure returns (uint32);

/// @notice Indicates if a royalty policy is whitelisted
/// @param royaltyPolicy The address of the royalty policy
Expand Down Expand Up @@ -139,7 +169,16 @@ interface IRoyaltyModule is IModule {
/// @param ipId The ID of IP asset
function ipRoyaltyVaults(address ipId) external view returns (address);

/// @notice Returns the global royalty stack for whitelisted royalty policies and a given IP asset
/// @param ipId The ID of IP asset
function globalRoyaltyStack(address ipId) external view returns (uint32);

/// @notice Returns the accumulated royalty policies for a given IP asset
/// @param ipId The ID of IP asset
function accumulatedRoyaltyPolicies(address ipId) external view returns (address[] memory);

/// @notice Returns the total lifetime revenue tokens received for a given IP asset
/// @param ipId The ID of IP asset
/// @param token The token address
function totalRevenueTokensReceived(address ipId, address token) external view returns (uint256);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ interface IExternalRoyaltyPolicy {
/// @param ipId The ipId of the IP asset
/// @param licensePercent The percentage of the license
/// @return The amount of royalty tokens required to link a child to a given IP asset
function rtsRequiredToLink(address ipId, uint32 licensePercent) external view returns (uint32);
function getPolicyRtsRequiredToLink(address ipId, uint32 licensePercent) external view returns (uint32);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.26;

import { IRoyaltyPolicy } from "../../../../interfaces/modules/royalty/policies/IRoyaltyPolicy.sol";

/// @title IGraphAwareRoyaltyPolicy interface
interface IGraphAwareRoyaltyPolicy is IRoyaltyPolicy {
/// @notice Event emitted when revenue tokens are transferred to a vault from a royalty policy
/// @param ipId The ipId of the IP asset
/// @param ancestorIpId The ancestor ipId of the IP asset whose vault will receive revenue tokens
/// @param token The address of the token that is transferred
/// @param amount The amount of tokens transferred
event RevenueTransferredToVault(address ipId, address ancestorIpId, address token, uint256 amount);

/// @notice Transfers to vault an amount of revenue tokens
/// @param ipId The ipId of the IP asset
/// @param ancestorIpId The ancestor ipId of the IP asset
/// @param token The token address to transfer
/// @param amount The amount of tokens to transfer
function transferToVault(address ipId, address ancestorIpId, address token, uint256 amount) external;

/// @notice Returns the royalty percentage between an IP asset and a given ancestor
/// @param ipId The ipId to get the royalty for
/// @param ancestorIpId The ancestor ipId to get the royalty for
/// @return The royalty percentage between an IP asset and a given ancestor
function getPolicyRoyalty(address ipId, address ancestorIpId) external returns (uint32);

/// @notice Returns the total lifetime revenue tokens transferred to an ancestor's vault from a given IP asset
/// @param ipId The ipId of the IP asset
/// @param ancestorIpId The ancestor ipId of the IP asset
/// @param token The token address to transfer
/// @return The total lifetime revenue tokens transferred to an ancestor's vault from a given IP asset
function getTransferredTokens(address ipId, address ancestorIpId, address token) external view returns (uint256);
}
19 changes: 14 additions & 5 deletions contracts/interfaces/modules/royalty/policies/IIpRoyaltyVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ pragma solidity 0.8.26;
interface IIpRoyaltyVault {
/// @notice Event emitted when a revenue token is added to a vault
/// @param token The address of the revenue token
/// @param vault The address of the vault
event RevenueTokenAddedToVault(address token, address vault);
/// @param amount The amount of revenue token added
event RevenueTokenAddedToVault(address token, uint256 amount);

/// @notice Event emitted when a snapshot is taken
/// @param snapshotId The snapshot id
Expand All @@ -33,10 +33,11 @@ interface IIpRoyaltyVault {
address rtReceiver
) external;

/// @notice Adds a new revenue token to the vault
/// @notice Updates the vault balance with the new amount of revenue token
/// @param token The address of the revenue token
/// @param amount The amount of revenue token to add
/// @dev Only callable by the royalty module or whitelisted royalty policy
function addIpRoyaltyVaultTokens(address token) external;
function updateVaultBalance(address token, uint256 amount) external;

/// @notice A function to snapshot the claimable revenue and royalty token amounts
/// @return The snapshot id
Expand All @@ -52,7 +53,11 @@ interface IIpRoyaltyVault {
/// @notice Allows token holders to claim revenue token based on the token balance at certain snapshot
/// @param snapshotId The snapshot id
/// @param tokenList The list of revenue tokens to claim
function claimRevenueByTokenBatch(uint256 snapshotId, address[] calldata tokenList) external;
/// @return The amount of revenue tokens claimed for each token
function claimRevenueByTokenBatch(
uint256 snapshotId,
address[] calldata tokenList
) external returns (uint256[] memory);

/// @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
Expand Down Expand Up @@ -81,6 +86,10 @@ interface IIpRoyaltyVault {
/// @notice The last snapshotted timestamp
function lastSnapshotTimestamp() external view returns (uint256);

/// @notice Amount of revenue token pending to be snapshotted
/// @param token The address of the revenue token
function pendingVaultAmount(address token) external view returns (uint256);

/// @notice Amount of revenue token in the claim vault
/// @param token The address of the revenue token
function claimVaultAmount(address token) external view returns (uint256);
Expand Down
16 changes: 9 additions & 7 deletions contracts/interfaces/modules/royalty/policies/IRoyaltyPolicy.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.26;

import { IExternalRoyaltyPolicy } from "./IExternalRoyaltyPolicy.sol";

/// @title RoyaltyPolicy interface
interface IRoyaltyPolicy {
interface IRoyaltyPolicy is IExternalRoyaltyPolicy {
/// @notice Executes royalty related logic on minting a license
/// @dev Enforced to be only callable by RoyaltyModule
/// @param ipId The ipId whose license is being minted (licensor)
Expand All @@ -17,17 +19,17 @@ interface IRoyaltyPolicy {
/// @param licenseRoyaltyPolicies The royalty policies of the license
/// @param licensesPercent The license percentages of the licenses being minted
/// @param externalData The external data custom to each the royalty policy
/// @return The royalty stack of the child ipId for a given royalty policy
function onLinkToParents(
address ipId,
address[] calldata parentIpIds,
address[] calldata licenseRoyaltyPolicies,
uint32[] calldata licensesPercent,
bytes calldata externalData
) external;
) external returns (uint32);

/// @notice Returns the amount of royalty tokens required to link a child to a given IP asset
/// @param ipId The ipId of the IP asset
/// @param licensePercent The percentage of the license
/// @return The amount of royalty tokens required to link a child to a given IP asset
function rtsRequiredToLink(address ipId, uint32 licensePercent) external view returns (uint32);
/// @notice Returns the royalty stack for a given IP asset
/// @param ipId The ID of the IP asset
/// @return royaltyStack Sum of the royalty percentages to be paid to ancestors for a given royalty policy
function getPolicyRoyaltyStack(address ipId) external view returns (uint32);
}

This file was deleted.

This file was deleted.

52 changes: 38 additions & 14 deletions contracts/lib/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -464,11 +464,8 @@ library Errors {
/// @notice Zero address provided for parent ipId.
error RoyaltyModule__ZeroParentIpId();

/// @notice Royalty token supply limit is exceeded.
error RoyaltyModule__AboveRoyaltyTokenSupplyLimit();

/// @notice Not a allowed royalty policy.
error RoyaltyModule__NotAllowedRoyaltyPolicy();
/// @notice Above maximum percentage.
error RoyaltyModule__AboveMaxPercent();

/// @notice Caller is unauthorized.
error RoyaltyModule__NotAllowedCaller();
Expand All @@ -494,9 +491,6 @@ library Errors {
/// @notice Royalty policy is already whitelisted or registered.
error RoyaltyModule__PolicyAlreadyWhitelistedOrRegistered();

/// @notice External Royalty Policy does not support IExternalRoyaltyPolicy interface.
error RoyaltyModule__ExternalRoyaltyPolicyInterfaceNotSupported();

/// @notice Royalty Policy is not whitelisted or registered.
error RoyaltyModule__NotWhitelistedOrRegisteredRoyaltyPolicy();

Expand All @@ -515,6 +509,9 @@ library Errors {
/// @notice Zero address for ip asset registry.
error RoyaltyModule__ZeroIpAssetRegistry();

/// @notice Not a whitelisted royalty token.
error RoyaltyModule__NotWhitelistedRoyaltyToken();

////////////////////////////////////////////////////////////////////////////
// Royalty Policy LAP //
////////////////////////////////////////////////////////////////////////////
Expand All @@ -525,18 +522,12 @@ library Errors {
/// @notice Zero address provided for Royalty Module.
error RoyaltyPolicyLAP__ZeroRoyaltyModule();

/// @notice Zero address provided for Dispute Module.
error RoyaltyPolicyLAP__ZeroDisputeModule();

/// @notice Zero address provided for IP Graph ACL.
error RoyaltyPolicyLAP__ZeroIPGraphACL();

/// @notice Caller is not the Royalty Module.
error RoyaltyPolicyLAP__NotRoyaltyModule();

/// @notice Total royalty stack exceeds the protocol limit.
error RoyaltyPolicyLAP__AboveRoyaltyStackLimit();

/// @notice IP is dispute tagged.
error RoyaltyPolicyLAP__IpTagged();

Expand All @@ -552,19 +543,46 @@ library Errors {
/// @notice There is no vault associated with the IP.
error RoyaltyPolicyLAP__InvalidTargetIpId();

/// @notice Zero claimable royalty.
error RoyaltyPolicyLAP__ZeroClaimableRoyalty();

/// @notice Amount exceeds the claimable royalty.
error RoyaltyPolicyLAP__ExceedsClaimableRoyalty();

/// @notice Above maximum percentage.
error RoyaltyPolicyLAP__AboveMaxPercent();

/// @notice Zero amount provided.
error RoyaltyPolicyLAP__ZeroAmount();

////////////////////////////////////////////////////////////////////////////
// Royalty Policy LRP //
////////////////////////////////////////////////////////////////////////////

/// @notice Caller is not the Royalty Module.
error RoyaltyPolicyLRP__NotRoyaltyModule();

/// @notice Zero address provided for IP Graph ACL.
error RoyaltyPolicyLRP__ZeroIPGraphACL();

/// @notice Zero address provided for Royalty Module.
error RoyaltyPolicyLRP__ZeroRoyaltyModule();

/// @notice Zero address provided for Access Manager in initializer.
error RoyaltyPolicyLRP__ZeroAccessManager();

/// @notice Zero claimable royalty.
error RoyaltyPolicyLRP__ZeroClaimableRoyalty();

/// @notice Claimer is not an ancestor of the IP.
error RoyaltyPolicyLRP__ExceedsClaimableRoyalty();

/// @notice Above maximum percentage.
error RoyaltyPolicyLRP__AboveMaxPercent();

/// @notice Zero amount provided.
error RoyaltyPolicyLRP__ZeroAmount();

////////////////////////////////////////////////////////////////////////////
// IP Royalty Vault //
////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -596,6 +614,12 @@ library Errors {
/// @notice IP Royalty Vault is paused.
error IpRoyaltyVault__EnforcedPause();

/// @notice The vault which is claiming does not belong to an ancestor IP.
error IpRoyaltyVault__VaultDoesNotBelongToAnAncestor();

/// @notice Zero amount provided.
error IpRoyaltyVault__ZeroAmount();

////////////////////////////////////////////////////////////////////////////
// Vault Controller //
////////////////////////////////////////////////////////////////////////////
Expand Down
Loading

0 comments on commit 73f655e

Please sign in to comment.