diff --git a/src/FeeCalculator.sol b/src/FeeCalculator.sol index be322e2..2504cc8 100644 --- a/src/FeeCalculator.sol +++ b/src/FeeCalculator.sol @@ -9,7 +9,7 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import {SD59x18, sd, intoUint256} from "@prb/math/src/SD59x18.sol"; -import "./interfaces/IFeeCalculator.sol"; +import {IFeeCalculator, FeeDistribution} from "./interfaces/IFeeCalculator.sol"; import "./interfaces/IPool.sol"; /// @title FeeCalculator @@ -142,7 +142,7 @@ contract FeeCalculator is IFeeCalculator, Ownable { external view override - returns (uint256 feeAmount) + returns (uint256 feeAmount, FeeDistribution memory feeDistribution) { require(depositAmount > 0, "depositAmount must be > 0"); @@ -150,18 +150,17 @@ contract FeeCalculator is IFeeCalculator, Ownable { require(feeAmount <= depositAmount, "Fee must be lower or equal to deposit amount"); require(feeAmount > 0, "Fee must be greater than 0"); + feeDistribution = calculateFeeShares(feeAmount); } /// @notice Calculates the fee shares and recipients based on the total fee. /// @param totalFee The total fee to be distributed. - /// @return recipients The addresses of the fee recipients. - /// @return feesDenominatedInPoolTokens The amount of fees each recipient should receive. - function calculateFeeShares(uint256 totalFee) - internal - view - returns (address[] memory recipients, uint256[] memory feesDenominatedInPoolTokens) - { - feesDenominatedInPoolTokens = new uint256[](_recipients.length); + /// @return feeDistribution The recipients and the amount of fees each + /// recipient should receive. + function calculateFeeShares(uint256 totalFee) internal view returns (FeeDistribution memory feeDistribution) { + uint256[] memory feesDenominatedInPoolTokens = new uint256[]( + _recipients.length + ); uint256 restFee = totalFee; @@ -170,8 +169,13 @@ contract FeeCalculator is IFeeCalculator, Ownable { restFee -= feesDenominatedInPoolTokens[i]; } - recipients = _recipients; - feesDenominatedInPoolTokens[0] += restFee; //we give rest of the fee (if any) to the first recipient + // If any fee is left, it is distributed to the first recipient. + // This may happen if any of the shares of the fee to be distributed + // has leftover from the division by 100 above. + feesDenominatedInPoolTokens[0] += restFee; + + feeDistribution.recipients = _recipients; + feeDistribution.shares = feesDenominatedInPoolTokens; } /// @notice Calculates the redemption fees for a given amount. @@ -184,7 +188,7 @@ contract FeeCalculator is IFeeCalculator, Ownable { external view override - returns (uint256 feeAmount) + returns (uint256 feeAmount, FeeDistribution memory feeDistribution) { require(redemptionAmount > 0, "redemptionAmount must be > 0"); @@ -192,30 +196,7 @@ contract FeeCalculator is IFeeCalculator, Ownable { require(feeAmount <= redemptionAmount, "Fee must be lower or equal to redemption amount"); require(feeAmount > 0, "Fee must be greater than 0"); - } - - /// @notice Calculates the fee shares and recipients for a deposit based on the total fee. - /// @param totalFee The total fee to be shared. - /// @return recipients The addresses of the fee recipients. - /// @return feesDenominatedInPoolTokens The amount of fees each recipient should receive. - function calculateDepositFeeShares(uint256 totalFee) - external - view - returns (address[] memory recipients, uint256[] memory feesDenominatedInPoolTokens) - { - return calculateFeeShares(totalFee); - } - - /// @notice Calculates the fee shares and recipients for a redemption based on the total fee. - /// @param totalFee The total fee to be shared. - /// @return recipients The addresses of the fee recipients. - /// @return feesDenominatedInPoolTokens The amount of fees each recipient should receive. - function calculateRedemptionFeeShares(uint256 totalFee) - external - view - returns (address[] memory recipients, uint256[] memory feesDenominatedInPoolTokens) - { - return calculateFeeShares(totalFee); + feeDistribution = calculateFeeShares(feeAmount); } /// @notice Gets the balance of the TCO2 token in a given pool. diff --git a/src/interfaces/IFeeCalculator.sol b/src/interfaces/IFeeCalculator.sol index f8515c3..9d114df 100644 --- a/src/interfaces/IFeeCalculator.sol +++ b/src/interfaces/IFeeCalculator.sol @@ -5,6 +5,11 @@ // If you encounter a vulnerability or an issue, please contact pragma solidity ^0.8.13; +struct FeeDistribution { + address[] recipients; + uint256[] shares; +} + /// @title IFeeCalculator /// @author Neutral Labs Inc. /// @notice This interface defines methods for calculating fees. @@ -18,7 +23,7 @@ interface IFeeCalculator { function calculateDepositFees(address tco2, address pool, uint256 depositAmount) external view - returns (uint256 feeAmount); + returns (uint256 feeAmount, FeeDistribution memory feeDistribution); /// @notice Calculates the redemption fees for a given amount. /// @param tco2 The address of the TCO2 token. @@ -29,23 +34,5 @@ interface IFeeCalculator { function calculateRedemptionFees(address tco2, address pool, uint256 redemptionAmount) external view - returns (uint256 feeAmount); - - /// @notice Calculates the fee shares and recipients for a deposit based on the total fee. - /// @param totalFee The total fee to be shared. - /// @return recipients The addresses of the fee recipients. - /// @return feesDenominatedInPoolTokens The amount of fees each recipient should receive. - function calculateDepositFeeShares(uint256 totalFee) - external - view - returns (address[] memory recipients, uint256[] memory feesDenominatedInPoolTokens); - - /// @notice Calculates the fee shares and recipients for a redemption based on the total fee. - /// @param totalFee The total fee to be shared. - /// @return recipients The addresses of the fee recipients. - /// @return feesDenominatedInPoolTokens The amount of fees each recipient should receive. - function calculateRedemptionFeeShares(uint256 totalFee) - external - view - returns (address[] memory recipients, uint256[] memory feesDenominatedInPoolTokens); + returns (uint256 feeAmount, FeeDistribution memory feeDistribution); } diff --git a/test/FeeCalculator.fuzzy.t.sol b/test/FeeCalculator.fuzzy.t.sol index ed2f43e..e944c8d 100644 --- a/test/FeeCalculator.fuzzy.t.sol +++ b/test/FeeCalculator.fuzzy.t.sol @@ -7,6 +7,7 @@ pragma solidity ^0.8.13; import {Test, console2} from "forge-std/Test.sol"; import {FeeCalculator} from "../src/FeeCalculator.sol"; +import {FeeDistribution} from "../src/interfaces/IFeeCalculator.sol"; import {SD59x18, sd, intoUint256 as sdIntoUint256} from "@prb/math/src/SD59x18.sol"; import {UD60x18, ud, intoUint256} from "@prb/math/src/UD60x18.sol"; import "./TestUtilities.sol"; @@ -120,7 +121,7 @@ contract FeeCalculatorTestFuzzy is Test { // Act try feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), redemptionAmount) returns ( - uint256 feeAmount + uint256 feeAmount, FeeDistribution memory ) { oneTimeFee = feeAmount; } catch Error(string memory reason) { @@ -145,7 +146,7 @@ contract FeeCalculatorTestFuzzy is Test { for (uint256 i = 0; i < numberOfRedemptions; i++) { uint256 redemption = equalRedemption + (i == 0 ? restRedemption : 0); try feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), redemption) returns ( - uint256 feeAmount + uint256 feeAmount, FeeDistribution memory ) { feeFromDividedRedemptions += feeAmount; total -= redemption; @@ -203,7 +204,7 @@ contract FeeCalculatorTestFuzzy is Test { // Act try feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount) returns ( - uint256 feeAmount + uint256 feeAmount, FeeDistribution memory ) { oneTimeFee = feeAmount; } catch Error(string memory reason) { @@ -223,7 +224,7 @@ contract FeeCalculatorTestFuzzy is Test { uint256 deposit = equalDeposit + (i == 0 ? restDeposit : 0); try feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), deposit) returns ( - uint256 feeAmount + uint256 feeAmount, FeeDistribution memory ) { feeFromDividedDeposits += feeAmount; total += deposit; @@ -276,8 +277,10 @@ contract FeeCalculatorTestFuzzy is Test { mockToken.setTokenBalance(address(mockPool), 100 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory gotRecipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory gotRecipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(gotRecipients.length, recipients.length); diff --git a/test/FeeCalculator.t.sol b/test/FeeCalculator.t.sol index 05de176..78e8e78 100644 --- a/test/FeeCalculator.t.sol +++ b/test/FeeCalculator.t.sol @@ -7,6 +7,7 @@ pragma solidity ^0.8.13; import {Test, console2} from "forge-std/Test.sol"; import {FeeCalculator} from "../src/FeeCalculator.sol"; +import {FeeDistribution} from "../src/interfaces/IFeeCalculator.sol"; import {SD59x18, sd, intoUint256 as sdIntoUint256} from "@prb/math/src/SD59x18.sol"; import {UD60x18, ud, intoUint256} from "@prb/math/src/UD60x18.sol"; import "./TestUtilities.sol"; @@ -72,12 +73,20 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 500 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (uint256 feeAmount, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert + assertEq(feeDistribution.recipients.length, feeDistribution.shares.length, "array length mismatch"); assertEq(recipients[0], feeRecipient); assertEq(fees[0], 9718378209069523938); + uint256 totalFee = 0; + for (uint256 i = 0; i < feeDistribution.shares.length; ++i) { + totalFee += feeDistribution.shares[i]; + } + assertEq(feeAmount, totalFee, "total fee mismatch"); } function testCalculateRedemptionFeesNormalCase() public { @@ -90,13 +99,20 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 500 * 1e18); // Act - uint256 feeAmount = + (uint256 feeAmount, FeeDistribution memory feeDistribution) = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), redemptionAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateRedemptionFeeShares(feeAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert + assertEq(feeDistribution.recipients.length, feeDistribution.shares.length, "array length mismatch"); assertEq(recipients[0], feeRecipient); assertEq(fees[0], 2833521467902860250); + uint256 totalFee = 0; + for (uint256 i = 0; i < feeDistribution.shares.length; ++i) { + totalFee += feeDistribution.shares[i]; + } + assertEq(feeAmount, totalFee, "total fee mismatch"); } function testCalculateRedemptionFees_ZeroMonopolization_MaximumFees() public { @@ -109,9 +125,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1 * 1e18); // Act - uint256 feeAmount = + (, FeeDistribution memory feeDistribution) = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), redemptionAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateRedemptionFeeShares(feeAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -130,9 +147,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1e6 * 1e18); // Act - uint256 feeAmount = + (, FeeDistribution memory feeDistribution) = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), redemptionAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateRedemptionFeeShares(feeAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -159,8 +177,10 @@ contract FeeCalculatorTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient1); @@ -190,8 +210,10 @@ contract FeeCalculatorTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient1); @@ -211,8 +233,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 15462 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -260,8 +284,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -278,8 +304,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -315,8 +343,10 @@ contract FeeCalculatorTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient1); @@ -361,8 +391,10 @@ contract FeeCalculatorTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient1); @@ -388,8 +420,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1e6 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -480,8 +514,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 0); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -498,8 +534,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 0); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -530,9 +568,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1000); // Act - uint256 feeAmount = + (, FeeDistribution memory feeDistribution) = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), redemptionAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateRedemptionFeeShares(feeAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -549,8 +588,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1000); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -567,8 +608,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 999); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -585,8 +628,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 0); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -604,8 +649,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), supply - 1); // Act - uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateRedemptionFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -622,8 +669,10 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 55661911070827884041095553095); // Act - uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateRedemptionFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -765,8 +814,9 @@ contract FeeCalculatorTest is Test { feeCalculator.setDepositFeeScale(0.09 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), 100 * 1e18); - (, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), 100 * 1e18); + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(fees[0], 9718378209069523938 / 2); @@ -780,8 +830,9 @@ contract FeeCalculatorTest is Test { feeCalculator.setDepositFeeRatioScale(0.2 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), 100 * 1e18); - (, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), 100 * 1e18); + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(fees[0], 1299819671838098442); @@ -795,8 +846,9 @@ contract FeeCalculatorTest is Test { feeCalculator.setSingleAssetDepositRelativeFee(0.67 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), 100 * 1e18); - (, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), 100 * 1e18); + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(fees[0], 67 * 1e18); @@ -810,8 +862,9 @@ contract FeeCalculatorTest is Test { feeCalculator.setRedemptionFeeScale(0.4 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), 100e18); - (, uint256[] memory fees) = feeCalculator.calculateRedemptionFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), 100e18); + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(fees[0], 3778028623870480400); @@ -825,8 +878,9 @@ contract FeeCalculatorTest is Test { feeCalculator.setRedemptionFeeShift(0.5 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), 100e18); - (, uint256[] memory fees) = feeCalculator.calculateRedemptionFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), 100e18); + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(fees[0], 2303907724666580660); @@ -840,8 +894,9 @@ contract FeeCalculatorTest is Test { feeCalculator.setSingleAssetRedemptionRelativeFee(0.83 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), 100 * 1e18); - (, uint256[] memory fees) = feeCalculator.calculateRedemptionFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), 100 * 1e18); + uint256[] memory fees = feeDistribution.shares; assertEq(fees[0], 83 * 1e18); } @@ -857,8 +912,9 @@ contract FeeCalculatorTest is Test { feeCalculator.setDustAssetRedemptionRelativeFee(0.91 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); - (, uint256[] memory fees) = feeCalculator.calculateRedemptionFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(fees[0], depositAmount * 91 / 100); diff --git a/test/FeeCalculatorLaunchParams.fuzzy.t.sol b/test/FeeCalculatorLaunchParams.fuzzy.t.sol index 89c893a..b77d399 100644 --- a/test/FeeCalculatorLaunchParams.fuzzy.t.sol +++ b/test/FeeCalculatorLaunchParams.fuzzy.t.sol @@ -7,6 +7,7 @@ pragma solidity ^0.8.13; import {Test, console2} from "forge-std/Test.sol"; import {FeeCalculator} from "../src/FeeCalculator.sol"; +import {FeeDistribution} from "../src/interfaces/IFeeCalculator.sol"; import "./TestUtilities.sol"; contract FeeCalculatorLaunchParamsTestFuzzy is Test { @@ -116,7 +117,7 @@ contract FeeCalculatorLaunchParamsTestFuzzy is Test { // Act try feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount) returns ( - uint256 feeAmount + uint256 feeAmount, FeeDistribution memory ) { oneTimeFee = feeAmount; } catch Error(string memory reason) { @@ -137,7 +138,7 @@ contract FeeCalculatorLaunchParamsTestFuzzy is Test { uint256 deposit = equalDeposit + (i == 0 ? restDeposit : 0); try feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), deposit) returns ( - uint256 feeAmount + uint256 feeAmount, FeeDistribution memory ) { feeFromDividedDeposits += feeAmount; total += deposit; diff --git a/test/FeeCalculatorLaunchParams.t.sol b/test/FeeCalculatorLaunchParams.t.sol index d31ee20..f5d67ec 100644 --- a/test/FeeCalculatorLaunchParams.t.sol +++ b/test/FeeCalculatorLaunchParams.t.sol @@ -7,6 +7,7 @@ pragma solidity ^0.8.13; import {Test, console2} from "forge-std/Test.sol"; import {FeeCalculator} from "../src/FeeCalculator.sol"; +import {FeeDistribution} from "../src/interfaces/IFeeCalculator.sol"; import "./TestUtilities.sol"; contract FeeCalculatorLaunchParamsTest is Test { @@ -41,8 +42,10 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 500 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -70,8 +73,10 @@ contract FeeCalculatorLaunchParamsTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient1); @@ -101,8 +106,10 @@ contract FeeCalculatorLaunchParamsTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient1); @@ -122,8 +129,10 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 15462 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -172,8 +181,10 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -191,8 +202,10 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -229,8 +242,10 @@ contract FeeCalculatorLaunchParamsTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient1); @@ -276,8 +291,10 @@ contract FeeCalculatorLaunchParamsTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient1); @@ -304,8 +321,10 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 1e6 * 1e18); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -353,8 +372,10 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 0); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -385,8 +406,10 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 1000); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient); @@ -417,8 +440,10 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 0); // Act - uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); - (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateDepositFeeShares(feeAmount); + (, FeeDistribution memory feeDistribution) = + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + address[] memory recipients = feeDistribution.recipients; + uint256[] memory fees = feeDistribution.shares; // Assert assertEq(recipients[0], feeRecipient);