From 69fae657136818e2ada2433525efd2afca99f198 Mon Sep 17 00:00:00 2001 From: Spablob <99089658+Spablob@users.noreply.github.com> Date: Wed, 9 Oct 2024 05:23:52 +0100 Subject: [PATCH] add amount after fee to royalty events (#265) --- .../modules/royalty/IRoyaltyModule.sol | 21 ++++++++-- contracts/modules/royalty/RoyaltyModule.sol | 18 ++++++--- .../integration/flows/royalty/Royalty.t.sol | 24 ++++++++++-- .../modules/royalty/RoyaltyModule.t.sol | 38 ++++++++++++++++--- 4 files changed, 84 insertions(+), 17 deletions(-) diff --git a/contracts/interfaces/modules/royalty/IRoyaltyModule.sol b/contracts/interfaces/modules/royalty/IRoyaltyModule.sol index c682bf72..8b25d4de 100644 --- a/contracts/interfaces/modules/royalty/IRoyaltyModule.sol +++ b/contracts/interfaces/modules/royalty/IRoyaltyModule.sol @@ -29,14 +29,29 @@ interface IRoyaltyModule is IModule { /// @param sender The address that pays the royalties on behalf of the payer ID of IP asset /// @param token The token that is used to pay the royalties /// @param amount The amount that is paid - event RoyaltyPaid(address receiverIpId, address payerIpId, address sender, address token, uint256 amount); + /// @param amountAfterFee The amount after fee + event RoyaltyPaid( + address receiverIpId, + address payerIpId, + address sender, + address token, + uint256 amount, + uint256 amountAfterFee + ); /// @notice Event emitted when the license minting fee is paid /// @param receiverIpId The ipId that receives the royalties /// @param payerAddress The address that pays the royalties /// @param token The token that is used to pay the royalties - /// @param amount The amount paid - event LicenseMintingFeePaid(address receiverIpId, address payerAddress, address token, uint256 amount); + /// @param amount The amount that is paid + /// @param amountAfterFee The amount after fee + event LicenseMintingFeePaid( + address receiverIpId, + address payerAddress, + address token, + uint256 amount, + uint256 amountAfterFee + ); /// @notice Event emitted when a royalty policy is registered /// @param externalRoyaltyPolicy The address of the external royalty policy diff --git a/contracts/modules/royalty/RoyaltyModule.sol b/contracts/modules/royalty/RoyaltyModule.sol index b5e08f24..d91e440e 100644 --- a/contracts/modules/royalty/RoyaltyModule.sol +++ b/contracts/modules/royalty/RoyaltyModule.sol @@ -338,9 +338,9 @@ contract RoyaltyModule is IRoyaltyModule, VaultController, ReentrancyGuardUpgrad address token, uint256 amount ) external nonReentrant whenNotPaused { - _payRoyalty(receiverIpId, msg.sender, token, amount); + uint256 amountAfterFee = _payRoyalty(receiverIpId, msg.sender, token, amount); - emit RoyaltyPaid(receiverIpId, payerIpId, msg.sender, token, amount); + emit RoyaltyPaid(receiverIpId, payerIpId, msg.sender, token, amount, amountAfterFee); } /// @notice Allows to pay the minting fee for a license @@ -354,9 +354,9 @@ contract RoyaltyModule is IRoyaltyModule, VaultController, ReentrancyGuardUpgrad address token, uint256 amount ) external onlyLicensingModule { - _payRoyalty(receiverIpId, payerAddress, token, amount); + uint256 amountAfterFee = _payRoyalty(receiverIpId, payerAddress, token, amount); - emit LicenseMintingFeePaid(receiverIpId, payerAddress, token, amount); + emit LicenseMintingFeePaid(receiverIpId, payerAddress, token, amount, amountAfterFee); } /// @notice Returns the number of ancestors for a given IP asset @@ -542,7 +542,13 @@ contract RoyaltyModule is IRoyaltyModule, VaultController, ReentrancyGuardUpgrad /// @param payerAddress The address that pays the royalties /// @param token The token to use to pay the royalties /// @param amount The amount to pay - function _payRoyalty(address receiverIpId, address payerAddress, address token, uint256 amount) internal { + /// @return amountAfterFee The amount after fee + function _payRoyalty( + address receiverIpId, + address payerAddress, + address token, + uint256 amount + ) internal returns (uint256) { RoyaltyModuleStorage storage $ = _getRoyaltyModuleStorage(); if (amount == 0) revert Errors.RoyaltyModule__ZeroAmount(); @@ -562,6 +568,8 @@ contract RoyaltyModule is IRoyaltyModule, VaultController, ReentrancyGuardUpgrad if (remainingAmount > 0) _payToReceiverVault(receiverIpId, payerAddress, token, remainingAmount); $.totalRevenueTokensReceived[receiverIpId][token] += amountAfterFee; + + return amountAfterFee; } /// @notice Transfers to each whitelisted policy its share of the total payment diff --git a/test/foundry/integration/flows/royalty/Royalty.t.sol b/test/foundry/integration/flows/royalty/Royalty.t.sol index b57fccbb..836c8c62 100644 --- a/test/foundry/integration/flows/royalty/Royalty.t.sol +++ b/test/foundry/integration/flows/royalty/Royalty.t.sol @@ -66,7 +66,13 @@ contract Flows_Integration_Disputes is BaseIntegration { uint256[] memory licenseIds = new uint256[](3); vm.expectEmit(address(royaltyModule)); - emit IRoyaltyModule.LicenseMintingFeePaid(ipAcct[1], u.bob, address(erc20), mintAmount * mintingFee); + emit IRoyaltyModule.LicenseMintingFeePaid( + ipAcct[1], + u.bob, + address(erc20), + mintAmount * mintingFee, + mintAmount * mintingFee + ); licenseIds[0] = licensingModule.mintLicenseTokens({ licensorIpId: ipAcct[1], @@ -112,7 +118,13 @@ contract Flows_Integration_Disputes is BaseIntegration { erc20.approve(address(royaltyModule), 2 * mintAmount * mintingFee); vm.expectEmit(address(royaltyModule)); - emit IRoyaltyModule.LicenseMintingFeePaid(ipAcct[1], u.carl, address(erc20), mintAmount * mintingFee); + emit IRoyaltyModule.LicenseMintingFeePaid( + ipAcct[1], + u.carl, + address(erc20), + mintAmount * mintingFee, + mintAmount * mintingFee + ); licenseIds[0] = licensingModule.mintLicenseTokens({ licensorIpId: ipAcct[1], licenseTemplate: address(pilTemplate), @@ -123,7 +135,13 @@ contract Flows_Integration_Disputes is BaseIntegration { }); vm.expectEmit(address(royaltyModule)); - emit IRoyaltyModule.LicenseMintingFeePaid(ipAcct[2], u.carl, address(erc20), mintAmount * mintingFee); + emit IRoyaltyModule.LicenseMintingFeePaid( + ipAcct[2], + u.carl, + address(erc20), + mintAmount * mintingFee, + mintAmount * mintingFee + ); licenseIds[1] = licensingModule.mintLicenseTokens({ licensorIpId: ipAcct[2], // parent, is child IP of ipAcct[1] licenseTemplate: address(pilTemplate), diff --git a/test/foundry/modules/royalty/RoyaltyModule.t.sol b/test/foundry/modules/royalty/RoyaltyModule.t.sol index 10b0681b..bb06c019 100644 --- a/test/foundry/modules/royalty/RoyaltyModule.t.sol +++ b/test/foundry/modules/royalty/RoyaltyModule.t.sol @@ -22,8 +22,21 @@ contract TestRoyaltyModule is BaseTest { event RoyaltyPolicyWhitelistUpdated(address royaltyPolicy, bool allowed); event RoyaltyTokenWhitelistUpdated(address token, bool allowed); event RoyaltyPolicySet(address ipId, address royaltyPolicy, bytes data); - event RoyaltyPaid(address receiverIpId, address payerIpId, address sender, address token, uint256 amount); - event LicenseMintingFeePaid(address receiverIpId, address payerAddress, address token, uint256 amount); + event RoyaltyPaid( + address receiverIpId, + address payerIpId, + address sender, + address token, + uint256 amount, + uint256 amountAfterFee + ); + event LicenseMintingFeePaid( + address receiverIpId, + address payerAddress, + address token, + uint256 amount, + uint256 amountAfterFee + ); event RoyaltyVaultAddedToIp(address ipId, address ipRoyaltyVault); event ExternalRoyaltyPolicyRegistered(address externalRoyaltyPolicy); event LicensedWithRoyalty(address ipId, address royaltyPolicy, uint32 licensePercent, bytes externalData); @@ -886,7 +899,7 @@ contract TestRoyaltyModule is BaseTest { uint256 pendingVaultAmountBefore = IIpRoyaltyVault(ipRoyaltyVault).pendingVaultAmount(address(USDC)); vm.expectEmit(true, true, true, true, address(royaltyModule)); - emit RoyaltyPaid(receiverIpId, payerIpId, payerIpId, address(USDC), royaltyAmount); + emit RoyaltyPaid(receiverIpId, payerIpId, payerIpId, address(USDC), royaltyAmount, royaltyAmount); royaltyModule.payRoyaltyOnBehalf(receiverIpId, payerIpId, address(USDC), royaltyAmount); @@ -932,7 +945,14 @@ contract TestRoyaltyModule is BaseTest { uint256 usdcTreasuryAmountBefore = USDC.balanceOf(address(100)); vm.expectEmit(true, true, true, true, address(royaltyModule)); - emit RoyaltyPaid(receiverIpId, payerIpId, payerIpId, address(USDC), royaltyAmount); + emit RoyaltyPaid( + receiverIpId, + payerIpId, + payerIpId, + address(USDC), + royaltyAmount, + (royaltyAmount * 90e6) / royaltyModule.maxPercent() + ); royaltyModule.payRoyaltyOnBehalf(receiverIpId, payerIpId, address(USDC), royaltyAmount); @@ -1009,7 +1029,7 @@ contract TestRoyaltyModule is BaseTest { uint256 pendingVaultAmountBefore = IIpRoyaltyVault(ipRoyaltyVault).pendingVaultAmount(address(USDC)); vm.expectEmit(true, true, true, true, address(royaltyModule)); - emit LicenseMintingFeePaid(receiverIpId, payerAddress, address(USDC), royaltyAmount); + emit LicenseMintingFeePaid(receiverIpId, payerAddress, address(USDC), royaltyAmount, royaltyAmount); vm.startPrank(address(licensingModule)); royaltyModule.payLicenseMintingFee(receiverIpId, payerAddress, token, royaltyAmount); @@ -1058,7 +1078,13 @@ contract TestRoyaltyModule is BaseTest { uint256 usdcTreasuryAmountBefore = USDC.balanceOf(address(100)); vm.expectEmit(true, true, true, true, address(royaltyModule)); - emit LicenseMintingFeePaid(receiverIpId, payerAddress, address(USDC), royaltyAmount); + emit LicenseMintingFeePaid( + receiverIpId, + payerAddress, + address(USDC), + royaltyAmount, + (royaltyAmount * 90e6) / royaltyModule.maxPercent() + ); vm.startPrank(address(licensingModule)); royaltyModule.payLicenseMintingFee(receiverIpId, payerAddress, token, royaltyAmount);