Skip to content

Commit

Permalink
feat: support multiple tco2 and erc1155 redemption fee calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
kosecki123 committed Apr 23, 2024
1 parent c228b09 commit 0a70467
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 23 deletions.
23 changes: 15 additions & 8 deletions src/FlatFeeCalculator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@ contract FlatFeeCalculator is IFeeCalculator, Ownable {
function feeSetup(address[] memory recipients, uint256[] memory shares) external onlyOwner {
require(recipients.length == shares.length, "Recipients and shares arrays must have the same length");

uint256 totalShares = 0;
for (uint256 i = 0; i < shares.length; i++) {
totalShares += shares[i];
}
uint256 totalShares = sumOf(shares);
require(totalShares == 100, "Total shares must equal 100");

_recipients = recipients;
Expand Down Expand Up @@ -113,9 +110,10 @@ contract FlatFeeCalculator is IFeeCalculator, Ownable {
returns (FeeDistribution memory feeDistribution)
{
require(tco2s.length == redemptionAmounts.length, "length mismatch");
require(tco2s.length == 1, "only one");

feeDistribution = _calculateFee(redemptionAmounts[0]);
uint256 totalRedemptionAmount = sumOf(redemptionAmounts);

feeDistribution = _calculateFee(totalRedemptionAmount);
}

/// @notice Calculates the deposit fee for a given amount of an ERC1155 project.
Expand Down Expand Up @@ -151,9 +149,10 @@ contract FlatFeeCalculator is IFeeCalculator, Ownable {
) external view override returns (FeeDistribution memory feeDistribution) {
require(erc1155s.length == tokenIds.length, "erc1155s/tokenIds length mismatch");
require(erc1155s.length == redemptionAmounts.length, "erc1155s/redemptionAmounts length mismatch");
require(erc1155s.length == 1, "only one");

feeDistribution = _calculateFee(redemptionAmounts[0]);
uint256 totalRedemptionAmount = sumOf(redemptionAmounts);

feeDistribution = _calculateFee(totalRedemptionAmount);
}

/// @notice Returns the current fee setup.
Expand All @@ -176,4 +175,12 @@ contract FlatFeeCalculator is IFeeCalculator, Ownable {

return calculateFeeShares(feeAmount);
}

function sumOf(uint256[] memory array) private pure returns (uint256) {
uint256 total = 0;
for (uint i = 0; i < array.length; i++) {
total += array[i];
}
return total;
}
}
74 changes: 59 additions & 15 deletions test/FlatFeeCalculatorFuzzy/FlatFeeCalculator.fuzzy.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,32 @@ contract FlatFeeCalculatorTestFuzzy is Test {
assertEq(fees[0], 3000000000000000000);
}

function testCalculateRedemptionFeesMultipleTokensNormalCase() public {
// Arrange
// Set up your test data
uint256 redemptionAmount = 100 * 1e18;
address[] memory tco2s = new address[](3);
tco2s[0] = empty;
tco2s[1] = empty;
tco2s[2] = empty;
uint256[] memory redemptionAmounts = new uint256[](3);
redemptionAmounts[0] = redemptionAmount;
redemptionAmounts[1] = redemptionAmount;
redemptionAmounts[2] = redemptionAmount;

// Act
FeeDistribution memory feeDistribution = feeCalculator.calculateRedemptionFees(empty, tco2s, redemptionAmounts);
address[] memory recipients = feeDistribution.recipients;
uint256[] memory fees = feeDistribution.shares;

// Assert
assertEq(feeDistribution.recipients.length, feeDistribution.shares.length, "array length mismatch");
assertEq(recipients[0], feeRecipient);

uint256 expected = 3*redemptionAmount*feeCalculator.feeBasisPoints() / 10000;
assertEq(fees[0], expected);
}

function testCalculateRedemptionFeesDustAmount_ShouldThrow() public {
// Arrange
// Set up your test data
Expand Down Expand Up @@ -137,39 +163,57 @@ contract FlatFeeCalculatorTestFuzzy is Test {
assertEq(feeDistribution.shares[0], expected);
}

function testCalculateRedemptionAmount_TCO2(uint256 redemptionAmount) public {
function testCalculateRedemptionAmount_TCO2(uint256 redemptionAmount1, uint256 redemptionAmount2, uint256 redemptionAmount3) public {
// Arrange
vm.assume(redemptionAmount > 100);
vm.assume(redemptionAmount < 1e18 * 1e18);
vm.assume(redemptionAmount1 > 100);
vm.assume(redemptionAmount1 < 1e18 * 1e18);
vm.assume(redemptionAmount2 > 100);
vm.assume(redemptionAmount2 < 1e18 * 1e18);
vm.assume(redemptionAmount3 > 100);
vm.assume(redemptionAmount3 < 1e18 * 1e18);
// Act
address[] memory tco2s = new address[](1);
address[] memory tco2s = new address[](3);
tco2s[0] = empty;
uint256[] memory redemptionAmounts = new uint256[](1);
redemptionAmounts[0] = redemptionAmount;
tco2s[1] = empty;
tco2s[2] = empty;
uint256[] memory redemptionAmounts = new uint256[](3);
redemptionAmounts[0] = redemptionAmount1;
redemptionAmounts[1] = redemptionAmount2;
redemptionAmounts[2] = redemptionAmount3;

FeeDistribution memory feeDistribution = feeCalculator.calculateRedemptionFees(empty, tco2s, redemptionAmounts);

uint256 expected = redemptionAmount * feeCalculator.feeBasisPoints() / 10000;
uint256 expected = (redemptionAmount1 + redemptionAmount2 + redemptionAmount3) * feeCalculator.feeBasisPoints() / 10000;

assertEq(feeDistribution.shares[0], expected);
}

function testCalculateRedemptionAmount_ERC1155(uint256 redemptionAmount) public {
function testCalculateRedemptionAmount_ERC1155(uint256 redemptionAmount1, uint256 redemptionAmount2, uint256 redemptionAmount3) public {
// Arrange
vm.assume(redemptionAmount > 100);
vm.assume(redemptionAmount < 1e18 * 1e18);
vm.assume(redemptionAmount1 > 100);
vm.assume(redemptionAmount1 < 1e18 * 1e18);
vm.assume(redemptionAmount2 > 100);
vm.assume(redemptionAmount2 < 1e18 * 1e18);
vm.assume(redemptionAmount3 > 100);
vm.assume(redemptionAmount3 < 1e18 * 1e18);
// Act
address[] memory erc1155s = new address[](1);
address[] memory erc1155s = new address[](3);
erc1155s[0] = empty;
uint256[] memory tokenIds = new uint256[](1);
erc1155s[1] = empty;
erc1155s[2] = empty;
uint256[] memory tokenIds = new uint256[](3);
tokenIds[0] = 1;
uint256[] memory redemptionAmounts = new uint256[](1);
redemptionAmounts[0] = redemptionAmount;
tokenIds[1] = 2;
tokenIds[2] = 3;
uint256[] memory redemptionAmounts = new uint256[](3);
redemptionAmounts[0] = redemptionAmount1;
redemptionAmounts[1] = redemptionAmount2;
redemptionAmounts[2] = redemptionAmount3;

FeeDistribution memory feeDistribution =
feeCalculator.calculateRedemptionFees(empty, erc1155s, tokenIds, redemptionAmounts);

uint256 expected = redemptionAmount * feeCalculator.feeBasisPoints() / 10000;
uint256 expected = (redemptionAmount1 + redemptionAmount2 + redemptionAmount3) * feeCalculator.feeBasisPoints() / 10000;

assertEq(feeDistribution.shares[0], expected);
}
Expand Down

0 comments on commit 0a70467

Please sign in to comment.