From d4cf262240b5d8d7c2a36d9b7877293ac9387491 Mon Sep 17 00:00:00 2001 From: Michalis Kargakis Date: Wed, 20 Dec 2023 16:09:08 +0100 Subject: [PATCH] Break down fee calculator interfaces The pool contract needs to estimate the fee to charge for a deposit or redemption separately from executing the distribution of the total fee to the fee recipients because in between the two the pool contract needs to either burn the tokens from the user in case of a redemption or mint tokens to the user in case of a deposit. In order to best facilitate this requirement the current fee calculator interface needs to separate estimating the fee of a deposit/redemption from estimating the shares for each fee recipient. --- src/FeeCalculator.sol | 44 ++++---- src/interfaces/IDepositFeeCalculator.sol | 21 ---- src/interfaces/IFeeCalculator.sol | 40 +++++++ src/interfaces/IRedemptionFeeCalculator.sol | 21 ---- test/FeeCalculator.fuzzy.t.sol | 33 ++---- test/FeeCalculator.t.sol | 116 ++++++++++---------- test/FeeCalculatorLaunchParams.fuzzy.t.sol | 18 +-- test/FeeCalculatorLaunchParams.t.sol | 57 +++++----- 8 files changed, 162 insertions(+), 188 deletions(-) delete mode 100644 src/interfaces/IDepositFeeCalculator.sol create mode 100644 src/interfaces/IFeeCalculator.sol delete mode 100644 src/interfaces/IRedemptionFeeCalculator.sol diff --git a/src/FeeCalculator.sol b/src/FeeCalculator.sol index 5f279df..1405e2e 100644 --- a/src/FeeCalculator.sol +++ b/src/FeeCalculator.sol @@ -5,17 +5,17 @@ // If you encounter a vulnerability or an issue, please contact pragma solidity ^0.8.13; -import "./interfaces/IDepositFeeCalculator.sol"; -import "./interfaces/IRedemptionFeeCalculator.sol"; 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"; + /// @title FeeCalculator /// @author Neutral Labs Inc. /// @notice This contract calculates deposit and redemption fees for a given pool. -/// @dev It implements IDepositFeeCalculator and IRedemptionFeeCalculator interfaces. -contract FeeCalculator is IDepositFeeCalculator, IRedemptionFeeCalculator, Ownable { +/// @dev It implements the IFeeCalculator interface. +contract FeeCalculator is IFeeCalculator, Ownable { SD59x18 private zero = sd(0); SD59x18 private one = sd(1e18); @@ -131,34 +131,32 @@ contract FeeCalculator is IDepositFeeCalculator, IRedemptionFeeCalculator, Ownab _shares = shares; } - /// @notice Calculates the deposit fees for a given amount. + /// @notice Calculates the deposit fee for a given amount. /// @param tco2 The address of the TCO2 token. /// @param pool The address of the pool. /// @param depositAmount The amount to be deposited. - /// @return recipients The addresses of the fee recipients. - /// @return feesDenominatedInPoolTokens The amount of fees each recipient should receive. + /// @return feeAmount The fee to be charged in pool + /// tokens for this deposit. function calculateDepositFees(address tco2, address pool, uint256 depositAmount) external view override - returns (address[] memory recipients, uint256[] memory feesDenominatedInPoolTokens) + returns (uint256 feeAmount) { require(depositAmount > 0, "depositAmount must be > 0"); - uint256 totalFee = getDepositFee(depositAmount, getTokenBalance(pool, tco2), getTotalSupply(pool)); - - require(totalFee <= depositAmount, "Fee must be lower or equal to deposit amount"); - require(totalFee > 0, "Fee must be greater than 0"); + feeAmount = getDepositFee(depositAmount, getTokenBalance(pool, tco2), getTotalSupply(pool)); - return distributeFeeAmongShares(totalFee); + require(feeAmount <= depositAmount, "Fee must be lower or equal to deposit amount"); + require(feeAmount > 0, "Fee must be greater than 0"); } - /// @notice Distributes the total fee among the recipients according to their shares. + /// @notice Calculates the total fee among the recipients according to their shares. /// @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 distributeFeeAmongShares(uint256 totalFee) - private + function calculateFeeAmongShares(uint256 totalFee) + external view returns (address[] memory recipients, uint256[] memory feesDenominatedInPoolTokens) { @@ -179,22 +177,20 @@ contract FeeCalculator is IDepositFeeCalculator, IRedemptionFeeCalculator, Ownab /// @param tco2 The address of the TCO2 token. /// @param pool The address of the pool. /// @param redemptionAmount The amount to be redeemed. - /// @return recipients The addresses of the fee recipients. - /// @return feesDenominatedInPoolTokens The amount of fees each recipient should receive. + /// @return feeAmount The fee to be charged in pool + /// tokens for this redemption. function calculateRedemptionFees(address tco2, address pool, uint256 redemptionAmount) external view override - returns (address[] memory recipients, uint256[] memory feesDenominatedInPoolTokens) + returns (uint256 feeAmount) { require(redemptionAmount > 0, "redemptionAmount must be > 0"); - uint256 totalFee = getRedemptionFee(redemptionAmount, getTokenBalance(pool, tco2), getTotalSupply(pool)); - - require(totalFee <= redemptionAmount, "Fee must be lower or equal to redemption amount"); - require(totalFee > 0, "Fee must be greater than 0"); + feeAmount = getRedemptionFee(redemptionAmount, getTokenBalance(pool, tco2), getTotalSupply(pool)); - return distributeFeeAmongShares(totalFee); + require(feeAmount <= redemptionAmount, "Fee must be lower or equal to redemption amount"); + require(feeAmount > 0, "Fee must be greater than 0"); } /// @notice Gets the balance of the TCO2 token in a given pool. diff --git a/src/interfaces/IDepositFeeCalculator.sol b/src/interfaces/IDepositFeeCalculator.sol deleted file mode 100644 index faa99fe..0000000 --- a/src/interfaces/IDepositFeeCalculator.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Neutral Labs Inc. -// -// SPDX-License-Identifier: UNLICENSED - -// If you encounter a vulnerability or an issue, please contact -pragma solidity ^0.8.13; - -/// @title IDepositFeeCalculator -/// @author Neutral Labs Inc. -/// @notice This interface defines a method for calculating deposit fees. -interface IDepositFeeCalculator { - /// @notice Calculates the deposit fees for a given amount. - /// @param tco2 The address of the TCO2 token. - /// @param pool The address of the pool. - /// @param depositAmount The amount to be deposited. - /// @return recipients The addresses of the fee recipients. - /// @return feesDenominatedInPoolTokens The amount of fees each recipient should receive. - function calculateDepositFees(address tco2, address pool, uint256 depositAmount) - external - returns (address[] memory recipients, uint256[] memory feesDenominatedInPoolTokens); -} diff --git a/src/interfaces/IFeeCalculator.sol b/src/interfaces/IFeeCalculator.sol new file mode 100644 index 0000000..a22fa71 --- /dev/null +++ b/src/interfaces/IFeeCalculator.sol @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: 2023 Neutral Labs Inc. +// +// SPDX-License-Identifier: UNLICENSED + +// If you encounter a vulnerability or an issue, please contact +pragma solidity ^0.8.13; + +/// @title IFeeCalculator +/// @author Neutral Labs Inc. +/// @notice This interface defines methods for calculating fees. +interface IFeeCalculator { + /// @notice Calculates the deposit fee for a given amount. + /// @param tco2 The address of the TCO2 token. + /// @param pool The address of the pool. + /// @param depositAmount The amount to be deposited. + /// @return feeAmount The fee to be charged in pool + /// tokens for this deposit. + function calculateDepositFees(address tco2, address pool, uint256 depositAmount) + external + returns (uint256 feeAmount); + + /// @notice Calculates the redemption fees for a given amount. + /// @param tco2 The address of the TCO2 token. + /// @param pool The address of the pool. + /// @param redemptionAmount The amount to be redeemed. + /// @return feeAmount The fee to be charged in pool + /// tokens for this redemption. + function calculateRedemptionFees(address tco2, address pool, uint256 redemptionAmount) + external + returns (uint256 feeAmount); + + /// @notice Calculates the total fee among the recipients according to their shares. + /// @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 calculateFeeAmongShares(uint256 totalFee) + external + view + returns (address[] memory recipients, uint256[] memory feesDenominatedInPoolTokens); +} diff --git a/src/interfaces/IRedemptionFeeCalculator.sol b/src/interfaces/IRedemptionFeeCalculator.sol deleted file mode 100644 index e884e4d..0000000 --- a/src/interfaces/IRedemptionFeeCalculator.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Neutral Labs Inc. -// -// SPDX-License-Identifier: UNLICENSED - -// If you encounter a vulnerability or an issue, please contact -pragma solidity ^0.8.13; - -/// @title IRedemptionFeeCalculator -/// @author Neutral Labs Inc. -/// @notice This interface defines a method for calculating redemption fees. -interface IRedemptionFeeCalculator { - /// @notice Calculates the redemption fees for a given amount. - /// @param tco2 The address of the TCO2 token. - /// @param pool The address of the pool. - /// @param redemptionAmount The amount to be redeemed. - /// @return recipients The addresses of the fee recipients. - /// @return feesDenominatedInPoolTokens The amount of fees each recipient should receive. - function calculateRedemptionFees(address tco2, address pool, uint256 redemptionAmount) - external - returns (address[] memory recipients, uint256[] memory feesDenominatedInPoolTokens); -} diff --git a/test/FeeCalculator.fuzzy.t.sol b/test/FeeCalculator.fuzzy.t.sol index b09e6dc..fcb6f88 100644 --- a/test/FeeCalculator.fuzzy.t.sol +++ b/test/FeeCalculator.fuzzy.t.sol @@ -68,11 +68,8 @@ contract FeeCalculatorTestFuzzy is Test { // Act try feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount) returns ( - address[] memory recipients, uint256[] memory fees - ) { - // Assert - assertEq(recipients[0], feeRecipient); - } catch Error(string memory reason) { + uint256 feeAmount + ) {} catch Error(string memory reason) { assertTrue( keccak256(bytes("Fee must be greater than 0")) == keccak256(bytes(reason)) || keccak256(bytes("Fee must be lower or equal to deposit amount")) == keccak256(bytes(reason)), @@ -124,12 +121,9 @@ contract FeeCalculatorTestFuzzy is Test { // Act try feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), redemptionAmount) returns ( - address[] memory recipients, uint256[] memory fees + uint256 feeAmount ) { - oneTimeFee = fees[0]; - - // Assert - assertEq(recipients[0], feeRecipient); + oneTimeFee = feeAmount; } catch Error(string memory reason) { oneTimeRedemptionFailed = true; assertTrue( @@ -152,9 +146,9 @@ 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 ( - address[] memory recipients, uint256[] memory fees + uint256 feeAmount ) { - feeFromDividedRedemptions += fees[0]; + feeFromDividedRedemptions += feeAmount; total -= redemption; current -= redemption; mockPool.setTotalSupply(total); @@ -210,12 +204,9 @@ contract FeeCalculatorTestFuzzy is Test { // Act try feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount) returns ( - address[] memory recipients, uint256[] memory fees + uint256 feeAmount ) { - oneTimeFee = fees[0]; - - // Assert - assertEq(recipients[0], feeRecipient); + oneTimeFee = feeAmount; } catch Error(string memory reason) { oneTimeDepositFailed = true; assertTrue( @@ -233,9 +224,9 @@ contract FeeCalculatorTestFuzzy is Test { uint256 deposit = equalDeposit + (i == 0 ? restDeposit : 0); try feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), deposit) returns ( - address[] memory recipients, uint256[] memory fees + uint256 feeAmount ) { - feeFromDividedDeposits += fees[0]; + feeFromDividedDeposits += feeAmount; total += deposit; current += deposit; mockPool.setTotalSupply(total); @@ -286,8 +277,8 @@ contract FeeCalculatorTestFuzzy is Test { mockToken.setTokenBalance(address(mockPool), 100 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert for (uint256 i = 0; i < recipients.length; i++) { diff --git a/test/FeeCalculator.t.sol b/test/FeeCalculator.t.sol index 0f969d7..3ac8788 100644 --- a/test/FeeCalculator.t.sol +++ b/test/FeeCalculator.t.sol @@ -52,8 +52,8 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 500 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -70,8 +70,9 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 500 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = + uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), redemptionAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -88,8 +89,9 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = + uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), redemptionAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -108,8 +110,9 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1e6 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = + uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), redemptionAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -136,8 +139,8 @@ contract FeeCalculatorTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient1); @@ -167,8 +170,8 @@ contract FeeCalculatorTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient1); @@ -188,8 +191,8 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 15462 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -237,8 +240,8 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -255,8 +258,8 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -292,8 +295,8 @@ contract FeeCalculatorTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient1); @@ -338,8 +341,8 @@ contract FeeCalculatorTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient1); @@ -365,8 +368,8 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1e6 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -400,8 +403,7 @@ contract FeeCalculatorTest is Test { vm.expectRevert( "The total volume in the pool must be greater than or equal to the volume for an individual asset" ); - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); } function testCalculateRedemptionFees_CurrentGreaterThanTotal_ExceptionShouldBeThrown() public { @@ -417,8 +419,7 @@ contract FeeCalculatorTest is Test { vm.expectRevert( "The total volume in the pool must be greater than or equal to the volume for an individual asset" ); - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); + feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); } function testCalculateRedemptionFees_AmountGreaterThanCurrent_ExceptionShouldBeThrown() public { @@ -432,8 +433,7 @@ contract FeeCalculatorTest is Test { // Act vm.expectRevert("The amount to be redeemed cannot exceed the current balance of the pool"); - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); + feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); } function testCalculateRedemptionFees_ZeroRedemption_ExceptionShouldBeThrown() public { @@ -447,8 +447,7 @@ contract FeeCalculatorTest is Test { // Act & Assert vm.expectRevert("redemptionAmount must be > 0"); - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); + feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); } function testCalculateDepositFees_EmptyPool_FeeCappedAt10Percent() public { @@ -461,8 +460,8 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 0); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -479,8 +478,8 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 0); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -511,8 +510,9 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1000); // Act - (address[] memory recipients, uint256[] memory fees) = + uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), redemptionAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -529,8 +529,8 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 1000); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -547,8 +547,8 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 999); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -565,8 +565,8 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 0); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -584,8 +584,8 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), supply - 1); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -602,8 +602,8 @@ contract FeeCalculatorTest is Test { mockToken.setTokenBalance(address(mockPool), 55661911070827884041095553095); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -745,8 +745,8 @@ contract FeeCalculatorTest is Test { feeCalculator.setDepositFeeScale(0.09 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), 100 * 1e18); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), 100 * 1e18); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(fees[0], 9718378209069523938 / 2); @@ -760,8 +760,8 @@ contract FeeCalculatorTest is Test { feeCalculator.setDepositFeeRatioScale(0.2 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), 100 * 1e18); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), 100 * 1e18); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(fees[0], 1299819671838098442); @@ -775,8 +775,8 @@ contract FeeCalculatorTest is Test { feeCalculator.setSingleAssetDepositRelativeFee(0.67 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), 100 * 1e18); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), 100 * 1e18); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(fees[0], 67 * 1e18); @@ -790,8 +790,8 @@ contract FeeCalculatorTest is Test { feeCalculator.setRedemptionFeeScale(0.4 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), 100e18); + uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), 100e18); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(fees[0], 3778028623870480400); @@ -805,8 +805,8 @@ contract FeeCalculatorTest is Test { feeCalculator.setRedemptionFeeShift(0.5 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), 100e18); + uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), 100e18); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(fees[0], 2303907724666580660); @@ -820,8 +820,8 @@ contract FeeCalculatorTest is Test { feeCalculator.setSingleAssetRedemptionRelativeFee(0.83 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), 100 * 1e18); + uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), 100 * 1e18); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); assertEq(fees[0], 83 * 1e18); } @@ -837,8 +837,8 @@ contract FeeCalculatorTest is Test { feeCalculator.setDustAssetRedemptionRelativeFee(0.91 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateRedemptionFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(fees[0], depositAmount * 91 / 100); diff --git a/test/FeeCalculatorLaunchParams.fuzzy.t.sol b/test/FeeCalculatorLaunchParams.fuzzy.t.sol index 1b1eded..61c6c19 100644 --- a/test/FeeCalculatorLaunchParams.fuzzy.t.sol +++ b/test/FeeCalculatorLaunchParams.fuzzy.t.sol @@ -68,12 +68,7 @@ contract FeeCalculatorLaunchParamsTestFuzzy is Test { mockToken.setTokenBalance(address(mockPool), current); // Act - try feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount) returns ( - address[] memory recipients, uint256[] memory fees - ) { - // Assert - assertEq(recipients[0], feeRecipient); - } catch Error(string memory reason) { + try feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount) {} catch Error(string memory reason) { assertTrue( keccak256(bytes("Fee must be greater than 0")) == keccak256(bytes(reason)) || keccak256(bytes("Fee must be lower or equal to deposit amount")) == keccak256(bytes(reason)) @@ -120,12 +115,9 @@ contract FeeCalculatorLaunchParamsTestFuzzy is Test { // Act try feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount) returns ( - address[] memory recipients, uint256[] memory fees + uint256 feeAmount ) { - oneTimeFee = fees[0]; - - // Assert - assertEq(recipients[0], feeRecipient); + oneTimeFee = feeAmount; } catch Error(string memory reason) { oneTimeDepositFailed = true; assertTrue( @@ -144,9 +136,9 @@ contract FeeCalculatorLaunchParamsTestFuzzy is Test { uint256 deposit = equalDeposit + (i == 0 ? restDeposit : 0); try feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), deposit) returns ( - address[] memory recipients, uint256[] memory fees + uint256 feeAmount ) { - feeFromDividedDeposits += fees[0]; + feeFromDividedDeposits += feeAmount; total += deposit; current += deposit; mockPool.setTotalSupply(total); diff --git a/test/FeeCalculatorLaunchParams.t.sol b/test/FeeCalculatorLaunchParams.t.sol index 638646b..0e96ea2 100644 --- a/test/FeeCalculatorLaunchParams.t.sol +++ b/test/FeeCalculatorLaunchParams.t.sol @@ -41,8 +41,8 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 500 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -70,8 +70,8 @@ contract FeeCalculatorLaunchParamsTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient1); @@ -101,8 +101,8 @@ contract FeeCalculatorLaunchParamsTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient1); @@ -122,8 +122,8 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 15462 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -172,8 +172,8 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -191,8 +191,8 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -229,8 +229,8 @@ contract FeeCalculatorLaunchParamsTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient1); @@ -276,8 +276,8 @@ contract FeeCalculatorLaunchParamsTest is Test { feeCalculator.feeSetup(_recipients, _feeShares); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient1); @@ -304,8 +304,8 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 1e6 * 1e18); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -340,8 +340,7 @@ contract FeeCalculatorLaunchParamsTest is Test { vm.expectRevert( "The total volume in the pool must be greater than or equal to the volume for an individual asset" ); - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); } function testCalculateDepositFees_EmptyPool_FeeCappedAt10Percent() public { @@ -354,8 +353,8 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 0); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -373,8 +372,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Act vm.expectRevert("Deposit outside range"); - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); } function testCalculateDepositFees_TotalEqualCurrent_FeeCappedAt10Percent() public { @@ -387,8 +385,8 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 1000); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient); @@ -406,8 +404,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Act vm.expectRevert("Deposit outside range"); - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); } function testCalculateDepositFees_ZeroCurrent_NormalFees() public { @@ -420,8 +417,8 @@ contract FeeCalculatorLaunchParamsTest is Test { mockToken.setTokenBalance(address(mockPool), 0); // Act - (address[] memory recipients, uint256[] memory fees) = - feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + uint256 feeAmount = feeCalculator.calculateDepositFees(address(mockToken), address(mockPool), depositAmount); + (address[] memory recipients, uint256[] memory fees) = feeCalculator.calculateFeeAmongShares(feeAmount); // Assert assertEq(recipients[0], feeRecipient);