Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LILA-7980] Do not throw on zero fee returned #59

Merged
merged 1 commit into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/FeeCalculator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ contract FeeCalculator is IFeeCalculator, Ownable {
/// @dev Version-related parameters. VERSION keeps track of production
/// releases. VERSION_RELEASE_CANDIDATE keeps track of iterations
/// of a VERSION in our staging environment.
string public constant VERSION = "1.1.0";
string public constant VERSION = "1.2.0";
uint256 public constant VERSION_RELEASE_CANDIDATE = 1;

SD59x18 private _zero = sd(0);
Expand Down Expand Up @@ -406,7 +406,9 @@ contract FeeCalculator is IFeeCalculator, Ownable {
uint256 feeAmount = calculator(requestedAmount, projectSupply, totalPoolSupply);

require(feeAmount <= requestedAmount, "Fee must be lower or equal to requested amount");
require(feeAmount != 0, "Fee must be greater than 0");
if (feeAmount == 0) {
return FeeDistribution(new address[](0), new uint256[](0));
}

return calculateFeeShares(feeAmount);
}
Expand Down
6 changes: 4 additions & 2 deletions src/FlatFeeCalculator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ contract FlatFeeCalculator is IFeeCalculator, Ownable {
/// @dev Version-related parameters. VERSION keeps track of production
/// releases. VERSION_RELEASE_CANDIDATE keeps track of iterations
/// of a VERSION in our staging environment.
string public constant VERSION = "1.0.0";
string public constant VERSION = "1.1.0";
uint256 public constant VERSION_RELEASE_CANDIDATE = 2;

uint256 public feeBasisPoints = 300;
Expand Down Expand Up @@ -158,7 +158,9 @@ contract FlatFeeCalculator is IFeeCalculator, Ownable {
require(requestedAmount != 0, "requested amount must be > 0");

uint256 feeAmount = requestedAmount * feeBasisPoints / 10000;
require(feeAmount != 0, "Fee must be greater than 0");
if (feeAmount == 0) {
return FeeDistribution(new address[](0), new uint256[](0));
}

return calculateFeeShares(feeAmount);
}
Expand Down
16 changes: 10 additions & 6 deletions test/FeeCalculator/AbstractFeeCalculator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ abstract contract AbstractFeeCalculatorTest is Test {
assertEq(fees[0], 46413457506542766270);
}

function testCalculateDepositFees_DepositOfOneWei_ShouldThrowException() public {
function testCalculateDepositFees_DepositOfOneWei_ShouldNotThrowException() public {
// Arrange
// Set up your test data
uint256 depositAmount = 1;
Expand All @@ -264,11 +264,13 @@ abstract contract AbstractFeeCalculatorTest is Test {
setProjectSupply(address(mockToken), 1e4 * 1e18);

// Act
vm.expectRevert("Fee must be greater than 0");
calculateDepositFees(address(mockPool), address(mockToken), depositAmount);
FeeDistribution memory feeDistribution =
calculateDepositFees(address(mockPool), address(mockToken), depositAmount);
assertEq(feeDistribution.recipients.length, 0);
assertEq(feeDistribution.shares.length, 0);
}

function testCalculateDepositFees_DepositOfHundredWei_ShouldThrowError() public {
function testCalculateDepositFees_DepositOfHundredWei_ShouldNotThrowError() public {
//Note! This is a bug, where a very small deposit to a very large pool
//causes a == b because of precision limited by ratioDenominator in FeeCalculator

Expand All @@ -281,8 +283,10 @@ abstract contract AbstractFeeCalculatorTest is Test {
setProjectSupply(address(mockToken), 1e4 * 1e18);

// Act
vm.expectRevert("Fee must be greater than 0");
calculateDepositFees(address(mockPool), address(mockToken), depositAmount);
FeeDistribution memory feeDistribution =
calculateDepositFees(address(mockPool), address(mockToken), depositAmount);
assertEq(feeDistribution.recipients.length, 0);
assertEq(feeDistribution.shares.length, 0);
}

function testCalculateDepositFees_DepositOfHundredThousandsPartOfOne_NonzeroFee() public {
Expand Down
8 changes: 5 additions & 3 deletions test/FeeCalculatorFuzzy/AbstractFeeCalculator.fuzzy.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ abstract contract AbstractFeeCalculatorTestFuzzy is Test {
uint256 total
) public virtual;

function testCalculateDepositFees_FuzzyExtremelySmallDepositsToLargePool_ShouldThrowError(uint256 depositAmount)
function testCalculateDepositFees_FuzzyExtremelySmallDepositsToLargePool_ShouldNotThrowError(uint256 depositAmount)
public
{
vm.assume(depositAmount <= 1e-14 * 1e18);
Expand All @@ -66,8 +66,10 @@ abstract contract AbstractFeeCalculatorTestFuzzy is Test {
mockPool.setTotalSupply(1e12 * 1e18);
setProjectSupply(address(mockToken), 1e9 * 1e18);

vm.expectRevert("Fee must be greater than 0");
calculateDepositFees(address(mockPool), address(mockToken), depositAmount);
FeeDistribution memory feeDistribution =
calculateDepositFees(address(mockPool), address(mockToken), depositAmount);
assertEq(feeDistribution.recipients.length, 0);
assertEq(feeDistribution.shares.length, 0);
}

function testCalculateRedemptionFeesFuzzy_RedemptionDividedIntoOneChunkFeesGreaterOrEqualToOneRedemption(
Expand Down
25 changes: 10 additions & 15 deletions test/FeeCalculatorFuzzy/FeeCalculatorERC1155.fuzzy.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ contract FeeCalculatorERC1155TestFuzzy is AbstractFeeCalculatorTestFuzzy {
try feeCalculator.calculateDepositFees(address(mockPool), address(mockToken), 1, 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 requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be greater than 0' or 'Fee must be lower or equal to requested amount'"
keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be lower or equal to requested amount'"
);
}
}
Expand Down Expand Up @@ -95,9 +94,8 @@ contract FeeCalculatorERC1155TestFuzzy is AbstractFeeCalculatorTestFuzzy {
} catch Error(string memory reason) {
oneTimeRedemptionFailed = true;
assertTrue(
keccak256(bytes("Fee must be greater than 0")) == keccak256(bytes(reason))
|| keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be greater than 0' or 'Fee must be lower or equal to requested amount'"
keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be lower or equal to requested amount'"
);
}

Expand Down Expand Up @@ -125,9 +123,8 @@ contract FeeCalculatorERC1155TestFuzzy is AbstractFeeCalculatorTestFuzzy {
} catch Error(string memory reason) {
multipleTimesRedemptionFailedCount++;
assertTrue(
keccak256(bytes("Fee must be greater than 0")) == keccak256(bytes(reason))
|| keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be greater than 0' or 'Fee must be lower or equal to requested amount'"
keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be lower or equal to requested amount'"
);
}
}
Expand Down Expand Up @@ -168,9 +165,8 @@ contract FeeCalculatorERC1155TestFuzzy is AbstractFeeCalculatorTestFuzzy {
} catch Error(string memory reason) {
oneTimeDepositFailed = true;
assertTrue(
keccak256(bytes("Fee must be greater than 0")) == keccak256(bytes(reason))
|| keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be greater than 0' or 'Fee must be lower or equal to requested amount'"
keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be lower or equal to requested amount'"
);
}

Expand All @@ -192,9 +188,8 @@ contract FeeCalculatorERC1155TestFuzzy is AbstractFeeCalculatorTestFuzzy {
} catch Error(string memory reason) {
multipleTimesDepositFailedCount++;
assertTrue(
keccak256(bytes("Fee must be greater than 0")) == keccak256(bytes(reason))
|| keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be greater than 0' or 'Fee must be lower or equal to requested amount'"
keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be lower or equal to requested amount'"
);
}
}
Expand Down
25 changes: 10 additions & 15 deletions test/FeeCalculatorFuzzy/FeeCalculatorTCO2.fuzzy.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ contract FeeCalculatorTCO2TestFuzzy is AbstractFeeCalculatorTestFuzzy {
try feeCalculator.calculateDepositFees(address(mockPool), address(mockToken), 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 requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be greater than 0' or 'Fee must be lower or equal to requested amount'"
keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be lower or equal to requested amount'"
);
}
}
Expand Down Expand Up @@ -90,9 +89,8 @@ contract FeeCalculatorTCO2TestFuzzy is AbstractFeeCalculatorTestFuzzy {
} catch Error(string memory reason) {
oneTimeRedemptionFailed = true;
assertTrue(
keccak256(bytes("Fee must be greater than 0")) == keccak256(bytes(reason))
|| keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be greater than 0' or 'Fee must be lower or equal to requested amount'"
keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be lower or equal to requested amount'"
);
}

Expand Down Expand Up @@ -120,9 +118,8 @@ contract FeeCalculatorTCO2TestFuzzy is AbstractFeeCalculatorTestFuzzy {
} catch Error(string memory reason) {
multipleTimesRedemptionFailedCount++;
assertTrue(
keccak256(bytes("Fee must be greater than 0")) == keccak256(bytes(reason))
|| keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be greater than 0' or 'Fee must be lower or equal to requested amount'"
keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be lower or equal to requested amount'"
);
}
}
Expand Down Expand Up @@ -163,9 +160,8 @@ contract FeeCalculatorTCO2TestFuzzy is AbstractFeeCalculatorTestFuzzy {
} catch Error(string memory reason) {
oneTimeDepositFailed = true;
assertTrue(
keccak256(bytes("Fee must be greater than 0")) == keccak256(bytes(reason))
|| keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be greater than 0' or 'Fee must be lower or equal to requested amount'"
keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be lower or equal to requested amount'"
);
}

Expand All @@ -187,9 +183,8 @@ contract FeeCalculatorTCO2TestFuzzy is AbstractFeeCalculatorTestFuzzy {
} catch Error(string memory reason) {
multipleTimesDepositFailedCount++;
assertTrue(
keccak256(bytes("Fee must be greater than 0")) == keccak256(bytes(reason))
|| keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be greater than 0' or 'Fee must be lower or equal to requested amount'"
keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason)),
"error should be 'Fee must be lower or equal to requested amount'"
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ abstract contract AbstractFeeCalculatorLaunchParamsTest is Test {
assertEq(fees[0], 53013879215838797358);
}

function testCalculateDepositFees_DepositOfOneWei_ShouldThrowException() public {
function testCalculateDepositFees_DepositOfOneWei_ShouldNotThrowException() public {
// Arrange
// Set up your test data
uint256 depositAmount = 1;
Expand All @@ -157,11 +157,13 @@ abstract contract AbstractFeeCalculatorLaunchParamsTest is Test {
setProjectSupply(address(mockToken), 1e4 * 1e18);

// Act
vm.expectRevert("Fee must be greater than 0");
calculateDepositFees(address(mockPool), address(mockToken), depositAmount);
FeeDistribution memory feeDistribution =
calculateDepositFees(address(mockPool), address(mockToken), depositAmount);
assertEq(feeDistribution.recipients.length, 0);
assertEq(feeDistribution.shares.length, 0);
}

function testCalculateDepositFees_DepositOfHundredWei_ShouldThrowError() public {
function testCalculateDepositFees_DepositOfHundredWei_ShouldNotThrowError() public {
//Note! This is a bug, where a very small deposit to a very large pool
//causes a == b because of precision limited by ratioDenominator in FeeCalculator

Expand All @@ -174,8 +176,10 @@ abstract contract AbstractFeeCalculatorLaunchParamsTest is Test {
setProjectSupply(address(mockToken), 1e4 * 1e18);

// Act
vm.expectRevert("Fee must be greater than 0");
calculateDepositFees(address(mockPool), address(mockToken), depositAmount);
FeeDistribution memory feeDistribution =
calculateDepositFees(address(mockPool), address(mockToken), depositAmount);
assertEq(feeDistribution.recipients.length, 0);
assertEq(feeDistribution.shares.length, 0);
}

function testCalculateDepositFees_DepositOfHundredThousandsPartOfOne_NonzeroFee() public {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ abstract contract AbstractFeeCalculatorLaunchParamsTestFuzzy is Test {
uint256 total
) public virtual;

function testCalculateDepositFees_FuzzyExtremelySmallDepositsToLargePool_ShouldThrowError(uint256 depositAmount)
function testCalculateDepositFees_FuzzyExtremelySmallDepositsToLargePool_ShouldNotThrowError(uint256 depositAmount)
public
{
vm.assume(depositAmount <= 1e-14 * 1e18);
Expand All @@ -63,8 +63,10 @@ abstract contract AbstractFeeCalculatorLaunchParamsTestFuzzy is Test {
mockPool.setTotalSupply(1e12 * 1e18);
setProjectSupply(address(mockToken), 1e9 * 1e18);

vm.expectRevert("Fee must be greater than 0");
calculateDepositFees(address(mockPool), address(mockToken), depositAmount);
FeeDistribution memory feeDistribution =
calculateDepositFees(address(mockPool), address(mockToken), depositAmount);
assertEq(feeDistribution.recipients.length, 0);
assertEq(feeDistribution.shares.length, 0);
}

function testCalculateDepositFeesFuzzy_DepositDividedIntoOneChunkFeesGreaterOrEqualToOneDeposit(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ contract FeeCalculatorLaunchParamsERC1155TestFuzzy is AbstractFeeCalculatorLaunc
try feeCalculator.calculateDepositFees(address(mockPool), address(mockToken), 1, 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 requested amount")) == keccak256(bytes(reason))
keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason))
|| keccak256(bytes("Deposit outside range")) == keccak256(bytes(reason)),
"error should be 'Fee must be greater than 0' or 'Fee must be lower or equal to requested amount' or 'Deposit outside range'"
"error should be 'Fee must be lower or equal to requested amount' or 'Deposit outside range'"
);
}
}
Expand Down Expand Up @@ -80,10 +79,9 @@ contract FeeCalculatorLaunchParamsERC1155TestFuzzy is AbstractFeeCalculatorLaunc
} catch Error(string memory reason) {
oneTimeDepositFailed = true;
assertTrue(
keccak256(bytes("Fee must be greater than 0")) == keccak256(bytes(reason))
|| keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason))
keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason))
|| keccak256(bytes("Deposit outside range")) == keccak256(bytes(reason)),
"error should be 'Fee must be greater than 0' or 'Fee must be lower or equal to requested amount' or 'Deposit outside range'"
"error should be 'Fee must be lower or equal to requested amount' or 'Deposit outside range'"
);
}

Expand All @@ -105,10 +103,9 @@ contract FeeCalculatorLaunchParamsERC1155TestFuzzy is AbstractFeeCalculatorLaunc
} catch Error(string memory reason) {
multipleTimesDepositFailedCount++;
assertTrue(
keccak256(bytes("Fee must be greater than 0")) == keccak256(bytes(reason))
|| keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason))
keccak256(bytes("Fee must be lower or equal to requested amount")) == keccak256(bytes(reason))
|| keccak256(bytes("Deposit outside range")) == keccak256(bytes(reason)),
"error should be 'Fee must be greater than 0' or 'Fee must be lower or equal to requested amount' or 'Deposit outside range'"
"error should be 'Fee must be lower or equal to requested amount' or 'Deposit outside range'"
);
}
}
Expand Down
Loading
Loading