From 592d71654ba38a07c63347f58f15763fa89ce359 Mon Sep 17 00:00:00 2001 From: Michalis Kargakis Date: Wed, 7 Feb 2024 17:49:09 +0100 Subject: [PATCH] Use project composition to calculate fees Instead of calculating fees at the vintage level we should be calculating fees at the project level. In order to achieve that, use the newly implemented pool function `totalPerProjectTCO2Supply` to determine how many credits of a project are found in a pool. --- src/FeeCalculator.sol | 23 +++---- src/interfaces/IPool.sol | 9 ++- src/interfaces/ITCO2.sol | 31 ++++++++++ test/FeeCalculator.fuzzy.t.sol | 14 ++--- test/FeeCalculator.t.sol | 70 +++++++++++----------- test/FeeCalculatorLaunchParams.fuzzy.t.sol | 8 +-- test/FeeCalculatorLaunchParams.t.sol | 36 +++++------ test/TestUtilities.sol | 30 +++++++++- 8 files changed, 144 insertions(+), 77 deletions(-) create mode 100644 src/interfaces/ITCO2.sol diff --git a/src/FeeCalculator.sol b/src/FeeCalculator.sol index af8783a..a1e58af 100644 --- a/src/FeeCalculator.sol +++ b/src/FeeCalculator.sol @@ -11,6 +11,7 @@ import {SD59x18, sd, intoUint256} from "@prb/math/src/SD59x18.sol"; import {IFeeCalculator, FeeDistribution} from "./interfaces/IFeeCalculator.sol"; import "./interfaces/IPool.sol"; +import {VintageData, ITCO2} from "./interfaces/ITCO2.sol"; /// @title FeeCalculator /// @author Neutral Labs Inc. @@ -146,7 +147,7 @@ contract FeeCalculator is IFeeCalculator, Ownable { { require(depositAmount > 0, "depositAmount must be > 0"); - uint256 feeAmount = getDepositFee(depositAmount, getTokenBalance(pool, tco2), getTotalSupply(pool)); + uint256 feeAmount = getDepositFee(depositAmount, getProjectSupply(pool, tco2), getTotalSupply(pool)); require(feeAmount <= depositAmount, "Fee must be lower or equal to deposit amount"); require(feeAmount > 0, "Fee must be greater than 0"); @@ -195,22 +196,13 @@ contract FeeCalculator is IFeeCalculator, Ownable { require(redemptionAmount > 0, "redemptionAmount must be > 0"); - uint256 feeAmount = getRedemptionFee(redemptionAmount, getTokenBalance(pool, tco2), getTotalSupply(pool)); + uint256 feeAmount = getRedemptionFee(redemptionAmount, getProjectSupply(pool, tco2), getTotalSupply(pool)); require(feeAmount <= redemptionAmount, "Fee must be lower or equal to redemption amount"); require(feeAmount > 0, "Fee must be greater than 0"); feeDistribution = calculateFeeShares(feeAmount); } - /// @notice Gets the balance of the TCO2 token in a given pool. - /// @param pool The address of the pool. - /// @param tco2 The address of the TCO2 token. - /// @return The balance of the TCO2 token in the pool. - function getTokenBalance(address pool, address tco2) private view returns (uint256) { - uint256 tokenBalance = IERC20(tco2).balanceOf(pool); - return tokenBalance; - } - /// @notice Gets the total supply of a given pool. /// @param pool The address of the pool. /// @return The total supply of the pool. @@ -219,6 +211,15 @@ contract FeeCalculator is IFeeCalculator, Ownable { return totalSupply; } + /// @notice Gets the total supply of a project in the pool. + /// @param pool The address of the pool. + /// @return The total supply of the pool. + function getProjectSupply(address pool, address tco2) private view returns (uint256) { + VintageData memory vData = ITCO2(tco2).getVintageData(); + uint256 projectSupply = IPool(pool).totalPerProjectTCO2Supply(vData.projectTokenId); + return projectSupply; + } + /// @notice Calculates the ratios for deposit fee calculation. /// @param amount The amount to be deposited. /// @param current The current balance of the pool. diff --git a/src/interfaces/IPool.sol b/src/interfaces/IPool.sol index 331527a..f8e7aef 100644 --- a/src/interfaces/IPool.sol +++ b/src/interfaces/IPool.sol @@ -10,7 +10,14 @@ pragma solidity ^0.8.13; /// @notice This interface defines methods exposed by the Pool interface IPool { /// @notice Exposes the total TCO2 supply, tracked as the aggregation of deposit, - /// redemmption and bridge actions + /// redemption and bridge actions /// @return supply Current supply function totalTCO2Supply() external view returns (uint256 supply); + + /// @notice Exposes the total TCO2 supply of a project in a pool, + /// tracked as the aggregation of deposit, redemmption and bridge actions + /// @param projectTokenId The token id of the project as it's tracked + /// in the CarbonProjects contract + /// @return supply Current supply of a project in the pool + function totalPerProjectTCO2Supply(uint256 projectTokenId) external view returns (uint256 supply); } diff --git a/src/interfaces/ITCO2.sol b/src/interfaces/ITCO2.sol new file mode 100644 index 0000000..ef5e57d --- /dev/null +++ b/src/interfaces/ITCO2.sol @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2024 Neutral Labs Inc. +// +// SPDX-License-Identifier: UNLICENSED + +// If you encounter a vulnerability or an issue, please contact +pragma solidity ^0.8.13; + +struct VintageData { + /// @dev A human-readable string which differentiates this from other vintages in + /// the same project, and helps build the corresponding TCO2 name and symbol. + string name; + uint64 startTime; // UNIX timestamp + uint64 endTime; // UNIX timestamp + uint256 projectTokenId; + uint64 totalVintageQuantity; + bool isCorsiaCompliant; + bool isCCPcompliant; + string coBenefits; + string correspAdjustment; + string additionalCertification; + string uri; + string registry; +} + +/// @title ITCO2 +/// @notice This interface defines methods exposed by the TCO2 +interface ITCO2 { + /// @notice Get the vintage data for the TCO2 + /// @return vintageData Vintage data of the TCO2 + function getVintageData() external view returns (VintageData memory vintageData); +} diff --git a/test/FeeCalculator.fuzzy.t.sol b/test/FeeCalculator.fuzzy.t.sol index d9d2983..6b67770 100644 --- a/test/FeeCalculator.fuzzy.t.sol +++ b/test/FeeCalculator.fuzzy.t.sol @@ -45,7 +45,7 @@ contract FeeCalculatorTestFuzzy is Test { // Set up mock pool mockPool.setTotalSupply(1e12 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e9 * 1e18); + mockPool.setProjectSupply(1e9 * 1e18); vm.expectRevert("Fee must be greater than 0"); feeCalculator.calculateDepositFees(address(mockPool), address(mockToken), depositAmount); @@ -65,7 +65,7 @@ contract FeeCalculatorTestFuzzy is Test { // Set up mock pool mockPool.setTotalSupply(total); - mockToken.setTokenBalance(address(mockPool), current); + mockPool.setProjectSupply(current); // Act try feeCalculator.calculateDepositFees(address(mockPool), address(mockToken), depositAmount) {} @@ -114,7 +114,7 @@ contract FeeCalculatorTestFuzzy is Test { // Set up mock pool mockPool.setTotalSupply(total); - mockToken.setTokenBalance(address(mockPool), current); + mockPool.setProjectSupply(current); uint256 oneTimeFee = 0; bool oneTimeRedemptionFailed = false; uint256 multipleTimesRedemptionFailedCount = 0; @@ -158,7 +158,7 @@ contract FeeCalculatorTestFuzzy is Test { total -= redemption; current -= redemption; mockPool.setTotalSupply(total); - mockToken.setTokenBalance(address(mockPool), current); + mockPool.setProjectSupply(current); } catch Error(string memory reason) { multipleTimesRedemptionFailedCount++; assertTrue( @@ -204,7 +204,7 @@ contract FeeCalculatorTestFuzzy is Test { uint256 multipleTimesDepositFailedCount = 0; // Set up mock pool mockPool.setTotalSupply(total); - mockToken.setTokenBalance(address(mockPool), current); + mockPool.setProjectSupply(current); uint256 oneTimeFee = 0; @@ -236,7 +236,7 @@ contract FeeCalculatorTestFuzzy is Test { total += deposit; current += deposit; mockPool.setTotalSupply(total); - mockToken.setTokenBalance(address(mockPool), current); + mockPool.setProjectSupply(current); } catch Error(string memory reason) { multipleTimesDepositFailedCount++; assertTrue( @@ -280,7 +280,7 @@ contract FeeCalculatorTestFuzzy is Test { uint256 depositAmount = 100 * 1e18; // Set up mock pool mockPool.setTotalSupply(200 * 1e18); - mockToken.setTokenBalance(address(mockPool), 100 * 1e18); + mockPool.setProjectSupply(100 * 1e18); // Act FeeDistribution memory feeDistribution = diff --git a/test/FeeCalculator.t.sol b/test/FeeCalculator.t.sol index a14be2f..2679969 100644 --- a/test/FeeCalculator.t.sol +++ b/test/FeeCalculator.t.sol @@ -70,7 +70,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); // Act FeeDistribution memory feeDistribution = @@ -95,7 +95,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); // Act FeeDistribution memory feeDistribution = @@ -120,7 +120,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1e6 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1 * 1e18); + mockPool.setProjectSupply(1 * 1e18); // Act FeeDistribution memory feeDistribution = @@ -146,7 +146,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1e6 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e6 * 1e18); + mockPool.setProjectSupply(1e6 * 1e18); // Act FeeDistribution memory feeDistribution = @@ -168,7 +168,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); address[] memory _recipients = new address[](2); _recipients[0] = feeRecipient1; @@ -201,7 +201,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); address[] memory _recipients = new address[](2); _recipients[0] = feeRecipient1; @@ -232,7 +232,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(53461 * 1e18); - mockToken.setTokenBalance(address(mockPool), 15462 * 1e18); + mockPool.setProjectSupply(15462 * 1e18); // Act FeeDistribution memory feeDistribution = @@ -252,7 +252,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1e5 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); + mockPool.setProjectSupply(1e4 * 1e18); // Act vm.expectRevert("Fee must be greater than 0"); @@ -269,7 +269,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1e5 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); + mockPool.setProjectSupply(1e4 * 1e18); // Act vm.expectRevert("Fee must be greater than 0"); @@ -283,7 +283,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1e5 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); + mockPool.setProjectSupply(1e4 * 1e18); // Act FeeDistribution memory feeDistribution = @@ -303,7 +303,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1e5 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); + mockPool.setProjectSupply(1e4 * 1e18); // Act FeeDistribution memory feeDistribution = @@ -328,7 +328,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1e5 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); + mockPool.setProjectSupply(1e4 * 1e18); address[] memory _recipients = new address[](5); _recipients[0] = feeRecipient1; @@ -376,7 +376,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1e5 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); + mockPool.setProjectSupply(1e4 * 1e18); address[] memory _recipients = new address[](5); _recipients[0] = feeRecipient1; @@ -419,7 +419,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(100 * 1e6 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e6 * 1e18); + mockPool.setProjectSupply(1e6 * 1e18); // Act FeeDistribution memory feeDistribution = @@ -439,7 +439,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); // Act vm.expectRevert("depositAmount must be > 0"); @@ -453,7 +453,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1500 * 1e18); + mockPool.setProjectSupply(1500 * 1e18); // Act vm.expectRevert( @@ -473,7 +473,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1500 * 1e18); + mockPool.setProjectSupply(1500 * 1e18); // Act & Assert vm.expectRevert( @@ -493,7 +493,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); // Act vm.expectRevert("The amount to be redeemed cannot exceed the current balance of the pool"); @@ -511,7 +511,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); // Act & Assert vm.expectRevert("redemptionAmount must be > 0"); @@ -525,7 +525,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(0); - mockToken.setTokenBalance(address(mockPool), 0); + mockPool.setProjectSupply(0); // Act FeeDistribution memory feeDistribution = @@ -545,7 +545,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1); - mockToken.setTokenBalance(address(mockPool), 0); + mockPool.setProjectSupply(0); // Act FeeDistribution memory feeDistribution = @@ -569,7 +569,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); // Act vm.expectRevert("redemptionAmount must be > 0"); @@ -587,7 +587,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000); - mockToken.setTokenBalance(address(mockPool), 1000); + mockPool.setProjectSupply(1000); // Act FeeDistribution memory feeDistribution = @@ -607,7 +607,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000); - mockToken.setTokenBalance(address(mockPool), 1000); + mockPool.setProjectSupply(1000); // Act FeeDistribution memory feeDistribution = @@ -627,7 +627,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000); - mockToken.setTokenBalance(address(mockPool), 999); + mockPool.setProjectSupply(999); // Act FeeDistribution memory feeDistribution = @@ -647,7 +647,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 0); + mockPool.setProjectSupply(0); // Act FeeDistribution memory feeDistribution = @@ -672,7 +672,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool uint256 supply = 100000 * 1e18; mockPool.setTotalSupply(100000 * 1e18); - mockToken.setTokenBalance(address(mockPool), supply - 1); + mockPool.setProjectSupply(supply - 1); // Act FeeDistribution memory feeDistribution = @@ -696,7 +696,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(56636794628913227180683983236); - mockToken.setTokenBalance(address(mockPool), 55661911070827884041095553095); + mockPool.setProjectSupply(55661911070827884041095553095); // Act FeeDistribution memory feeDistribution = @@ -840,7 +840,7 @@ contract FeeCalculatorTest is Test { // Arrange // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); feeCalculator.setDepositFeeScale(0.09 * 1e18); // Act @@ -856,7 +856,7 @@ contract FeeCalculatorTest is Test { // Arrange // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); feeCalculator.setDepositFeeRatioScale(0.2 * 1e18); // Act @@ -872,7 +872,7 @@ contract FeeCalculatorTest is Test { // Arrange // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1000 * 1e18); + mockPool.setProjectSupply(1000 * 1e18); feeCalculator.setSingleAssetDepositRelativeFee(0.67 * 1e18); // Act @@ -893,7 +893,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); feeCalculator.setRedemptionFeeScale(0.4 * 1e18); // Act @@ -914,7 +914,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); feeCalculator.setRedemptionFeeShift(0.5 * 1e18); // Act @@ -935,7 +935,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1000 * 1e18); + mockPool.setProjectSupply(1000 * 1e18); feeCalculator.setSingleAssetRedemptionRelativeFee(0.83 * 1e18); // Act @@ -957,7 +957,7 @@ contract FeeCalculatorTest is Test { // Set up mock pool mockPool.setTotalSupply(56636794628913227180683983236); - mockToken.setTokenBalance(address(mockPool), 55661911070827884041095553095); + mockPool.setProjectSupply(55661911070827884041095553095); feeCalculator.setDustAssetRedemptionRelativeFee(0.91 * 1e18); // Act diff --git a/test/FeeCalculatorLaunchParams.fuzzy.t.sol b/test/FeeCalculatorLaunchParams.fuzzy.t.sol index 9c1576d..dbbd7d7 100644 --- a/test/FeeCalculatorLaunchParams.fuzzy.t.sol +++ b/test/FeeCalculatorLaunchParams.fuzzy.t.sol @@ -46,7 +46,7 @@ contract FeeCalculatorLaunchParamsTestFuzzy is Test { // Set up mock pool mockPool.setTotalSupply(1e12 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e9 * 1e18); + mockPool.setProjectSupply(1e9 * 1e18); vm.expectRevert("Fee must be greater than 0"); feeCalculator.calculateDepositFees(address(mockPool), address(mockToken), depositAmount); @@ -66,7 +66,7 @@ contract FeeCalculatorLaunchParamsTestFuzzy is Test { // Set up mock pool mockPool.setTotalSupply(total); - mockToken.setTokenBalance(address(mockPool), current); + mockPool.setProjectSupply(current); // Act try feeCalculator.calculateDepositFees(address(mockPool), address(mockToken), depositAmount) {} @@ -111,7 +111,7 @@ contract FeeCalculatorLaunchParamsTestFuzzy is Test { uint256 multipleTimesDepositFailedCount = 0; // Set up mock pool mockPool.setTotalSupply(total); - mockToken.setTokenBalance(address(mockPool), current); + mockPool.setProjectSupply(current); uint256 oneTimeFee = 0; @@ -144,7 +144,7 @@ contract FeeCalculatorLaunchParamsTestFuzzy is Test { total += deposit; current += deposit; mockPool.setTotalSupply(total); - mockToken.setTokenBalance(address(mockPool), current); + mockPool.setProjectSupply(current); } catch Error(string memory reason) { multipleTimesDepositFailedCount++; assertTrue( diff --git a/test/FeeCalculatorLaunchParams.t.sol b/test/FeeCalculatorLaunchParams.t.sol index 3e4ee52..6be28fc 100644 --- a/test/FeeCalculatorLaunchParams.t.sol +++ b/test/FeeCalculatorLaunchParams.t.sol @@ -39,7 +39,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); // Act FeeDistribution memory feeDistribution = @@ -62,7 +62,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); address[] memory _recipients = new address[](2); _recipients[0] = feeRecipient1; @@ -95,7 +95,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); address[] memory _recipients = new address[](2); _recipients[0] = feeRecipient1; @@ -126,7 +126,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(53461 * 1e18); - mockToken.setTokenBalance(address(mockPool), 15462 * 1e18); + mockPool.setProjectSupply(15462 * 1e18); // Act FeeDistribution memory feeDistribution = @@ -147,7 +147,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1e5 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); + mockPool.setProjectSupply(1e4 * 1e18); // Act vm.expectRevert("Fee must be greater than 0"); @@ -164,7 +164,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1e5 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); + mockPool.setProjectSupply(1e4 * 1e18); // Act vm.expectRevert("Fee must be greater than 0"); @@ -178,7 +178,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1e5 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); + mockPool.setProjectSupply(1e4 * 1e18); // Act FeeDistribution memory feeDistribution = @@ -199,7 +199,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1e5 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); + mockPool.setProjectSupply(1e4 * 1e18); // Act FeeDistribution memory feeDistribution = @@ -225,7 +225,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1e5 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); + mockPool.setProjectSupply(1e4 * 1e18); address[] memory _recipients = new address[](5); _recipients[0] = feeRecipient1; @@ -274,7 +274,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1e5 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e4 * 1e18); + mockPool.setProjectSupply(1e4 * 1e18); address[] memory _recipients = new address[](5); _recipients[0] = feeRecipient1; @@ -318,7 +318,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(100 * 1e6 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1e6 * 1e18); + mockPool.setProjectSupply(1e6 * 1e18); // Act FeeDistribution memory feeDistribution = @@ -339,7 +339,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 500 * 1e18); + mockPool.setProjectSupply(500 * 1e18); // Act vm.expectRevert("depositAmount must be > 0"); @@ -353,7 +353,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 1500 * 1e18); + mockPool.setProjectSupply(1500 * 1e18); // Act vm.expectRevert( @@ -369,7 +369,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(0); - mockToken.setTokenBalance(address(mockPool), 0); + mockPool.setProjectSupply(0); // Act FeeDistribution memory feeDistribution = @@ -389,7 +389,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1); - mockToken.setTokenBalance(address(mockPool), 0); + mockPool.setProjectSupply(0); // Act vm.expectRevert("Deposit outside range"); @@ -403,7 +403,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1000); - mockToken.setTokenBalance(address(mockPool), 1000); + mockPool.setProjectSupply(1000); // Act FeeDistribution memory feeDistribution = @@ -423,7 +423,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1000); - mockToken.setTokenBalance(address(mockPool), 999); + mockPool.setProjectSupply(999); // Act vm.expectRevert("Deposit outside range"); @@ -437,7 +437,7 @@ contract FeeCalculatorLaunchParamsTest is Test { // Set up mock pool mockPool.setTotalSupply(1000 * 1e18); - mockToken.setTokenBalance(address(mockPool), 0); + mockPool.setProjectSupply(0); // Act FeeDistribution memory feeDistribution = diff --git a/test/TestUtilities.sol b/test/TestUtilities.sol index 0fc0e9a..79962e3 100644 --- a/test/TestUtilities.sol +++ b/test/TestUtilities.sol @@ -5,7 +5,9 @@ // If you encounter a vulnerability or an issue, please contact pragma solidity ^0.8.0; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +import {VintageData} from "../src/interfaces/ITCO2.sol"; library TestUtilities { function sumOf(uint256[] memory numbers) internal pure returns (uint256) { @@ -19,6 +21,7 @@ library TestUtilities { contract MockPool is IERC20 { uint256 private _totalSupply; + uint256 private _totalPerProjectSupply; function totalSupply() external view returns (uint256) { return _totalSupply; @@ -28,10 +31,18 @@ contract MockPool is IERC20 { return _totalSupply; } + function totalPerProjectTCO2Supply() external view returns (uint256) { + return _totalPerProjectSupply; + } + function setTotalSupply(uint256 ts) public { _totalSupply = ts; } + function setProjectSupply(uint256 ts) public { + _totalPerProjectSupply = ts; + } + function allowance(address, address) external pure override returns (uint256) { return 0; } @@ -79,4 +90,21 @@ contract MockToken is IERC20 { function totalSupply() external pure returns (uint256) { return 0; } + + function vintageData() external pure returns (VintageData memory) { + return VintageData({ + name: "test", + startTime: 0, + endTime: 0, + projectTokenId: 69, + totalVintageQuantity: 0, + isCorsiaCompliant: false, + isCCPcompliant: false, + coBenefits: "", + correspAdjustment: "", + additionalCertification: "", + uri: "", + registry: "" + }); + } }