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..89c893a 100644 --- a/test/FeeCalculatorLaunchParams.fuzzy.t.sol +++ b/test/FeeCalculatorLaunchParams.fuzzy.t.sol @@ -68,12 +68,8 @@ 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 +116,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 +137,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);