Skip to content

Commit

Permalink
refactor: change setMinimumFeeToZero to lowerMinimumFee
Browse files Browse the repository at this point in the history
  • Loading branch information
andreivladbrg committed Feb 26, 2025
1 parent 2d2cd49 commit fd96c70
Show file tree
Hide file tree
Showing 13 changed files with 94 additions and 68 deletions.
13 changes: 9 additions & 4 deletions src/abstracts/SablierMerkleBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ abstract contract SablierMerkleBase is
}

/// @inheritdoc ISablierMerkleBase
function setMinimumFeeToZero() external override {
function lowerMinimumFee(uint256 newFee) external override {
// Retrieve the factory admin.
address factoryAdmin = ISablierMerkleFactoryBase(FACTORY).admin();

Expand All @@ -205,13 +205,18 @@ abstract contract SablierMerkleBase is
revert Errors.SablierMerkleBase_CallerNotFactoryAdmin(factoryAdmin, msg.sender);
}

uint256 previousMinimumFee = minimumFee;
uint256 previousFee = minimumFee;

// Check: the new fee is less than the current fee.
if (newFee >= previousFee) {
revert Errors.SablierMerkleBase_NewFeeNotLower(previousFee, newFee);
}

// Effect: set the minimum fee to zero.
minimumFee = 0;
minimumFee = newFee;

// Log the event.
emit SetMinimumFeeToZero(factoryAdmin, previousMinimumFee);
emit LowerMinimumFee(factoryAdmin, newFee, previousFee);
}

/*//////////////////////////////////////////////////////////////////////////
Expand Down
11 changes: 6 additions & 5 deletions src/interfaces/ISablierMerkleBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ interface ISablierMerkleBase is IAdminable {
/// @notice Emitted when the admin claws back the unclaimed tokens.
event Clawback(address indexed admin, address indexed to, uint128 amount);

/// @notice Emitted when the minimum fee is set to zero.
event SetMinimumFeeToZero(address indexed factoryAdmin, uint256 previousFee);
/// @notice Emitted when the minimum fee is set to a lower value.
event LowerMinimumFee(address indexed factoryAdmin, uint256 newFee, uint256 previousFee);

/*//////////////////////////////////////////////////////////////////////////
CONSTANT FUNCTIONS
Expand Down Expand Up @@ -110,11 +110,12 @@ interface ISablierMerkleBase is IAdminable {
/// @return feeAmount The amount of native tokens (e.g., ETH) collected as fees.
function collectFees(address factoryAdmin) external returns (uint256 feeAmount);

/// @notice Sets the minimum fee required to claim the airdrop to zero.
/// @notice Sets the minimum fee to a lower value.
///
/// @dev Emits a {SetMinimumFeeToZero} event.
/// @dev Emits a {LowerMinimumFee} event.
///
/// Requirements:
/// - `msg.sender` must be the `FACTORY` admin.
function setMinimumFeeToZero() external;
/// - The new fee must be less than the current `minimumFee`.
function lowerMinimumFee(uint256 newFee) external;
}
3 changes: 3 additions & 0 deletions src/libraries/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ library Errors {
/// @notice Thrown when trying to claim with an invalid Merkle proof.
error SablierMerkleBase_InvalidProof();

/// @notice Thrown when trying to set a fee that is not lower than the current fee.
error SablierMerkleBase_NewFeeNotLower(uint256 currentFee, uint256 newFee);

/// @notice Thrown when trying to claim the same stream more than once.
error SablierMerkleBase_StreamClaimed(uint256 index);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { CollectFees_Integration_Test } from "./../shared/collect-fees/collectFe
import { GetFirstClaimTime_Integration_Test } from "./../shared/get-first-claim-time/getFirstClaimTime.t.sol";
import { HasClaimed_Integration_Test } from "./../shared/has-claimed/hasClaimed.t.sol";
import { HasExpired_Integration_Test } from "./../shared/has-expired/hasExpired.t.sol";
import { SetMinimumFeeToZero_Integration_Test } from "./../shared/set-minimum-fee-to-zero/setMinimumFeeToZero.t.sol";
import { LowerMinimumFee_Integration_Test } from "./../shared/lower-minimum-fee/lowerMinimumFee.t.sol";

/*//////////////////////////////////////////////////////////////////////////
NON-SHARED TESTS
Expand Down Expand Up @@ -84,9 +84,9 @@ contract HasExpired_MerkleInstant_Integration_Test is
}
}

contract SetMinimumFeeToZero_MerkleInstant_Integration_Test is
contract LowerMinimumFee_MerkleInstant_Integration_Test is
MerkleInstant_Integration_Shared_Test,
SetMinimumFeeToZero_Integration_Test
LowerMinimumFee_Integration_Test
{
function setUp() public override(MerkleInstant_Integration_Shared_Test, Integration_Test) {
MerkleInstant_Integration_Shared_Test.setUp();
Expand Down
6 changes: 3 additions & 3 deletions tests/integration/concrete/campaign/ll/MerkleLL.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { CollectFees_Integration_Test } from "./../shared/collect-fees/collectFe
import { GetFirstClaimTime_Integration_Test } from "./../shared/get-first-claim-time/getFirstClaimTime.t.sol";
import { HasClaimed_Integration_Test } from "./../shared/has-claimed/hasClaimed.t.sol";
import { HasExpired_Integration_Test } from "./../shared/has-expired/hasExpired.t.sol";
import { SetMinimumFeeToZero_Integration_Test } from "./../shared/set-minimum-fee-to-zero/setMinimumFeeToZero.t.sol";
import { LowerMinimumFee_Integration_Test } from "./../shared/lower-minimum-fee/lowerMinimumFee.t.sol";

/*//////////////////////////////////////////////////////////////////////////
NON-SHARED TESTS
Expand Down Expand Up @@ -75,9 +75,9 @@ contract HasExpired_MerkleLL_Integration_Test is MerkleLL_Integration_Shared_Tes
}
}

contract SetMinimumFeeToZero_MerkleLL_Integration_Test is
contract LowerMinimumFee_MerkleLL_Integration_Test is
MerkleLL_Integration_Shared_Test,
SetMinimumFeeToZero_Integration_Test
LowerMinimumFee_Integration_Test
{
function setUp() public override(MerkleLL_Integration_Shared_Test, Integration_Test) {
MerkleLL_Integration_Shared_Test.setUp();
Expand Down
6 changes: 3 additions & 3 deletions tests/integration/concrete/campaign/lt/MerkleLT.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { CollectFees_Integration_Test } from "./../shared/collect-fees/collectFe
import { GetFirstClaimTime_Integration_Test } from "./../shared/get-first-claim-time/getFirstClaimTime.t.sol";
import { HasClaimed_Integration_Test } from "./../shared/has-claimed/hasClaimed.t.sol";
import { HasExpired_Integration_Test } from "./../shared/has-expired/hasExpired.t.sol";
import { SetMinimumFeeToZero_Integration_Test } from "./../shared/set-minimum-fee-to-zero/setMinimumFeeToZero.t.sol";
import { LowerMinimumFee_Integration_Test } from "./../shared/lower-minimum-fee/lowerMinimumFee.t.sol";

/*//////////////////////////////////////////////////////////////////////////
NON-SHARED TESTS
Expand Down Expand Up @@ -75,9 +75,9 @@ contract HasExpired_MerkleLT_Integration_Test is MerkleLT_Integration_Shared_Tes
}
}

contract SetMinimumFeeToZero_MerkleLT_Integration_Test is
contract LowerMinimumFee_MerkleLT_Integration_Test is
MerkleLT_Integration_Shared_Test,
SetMinimumFeeToZero_Integration_Test
LowerMinimumFee_Integration_Test
{
function setUp() public override(MerkleLT_Integration_Shared_Test, Integration_Test) {
MerkleLT_Integration_Shared_Test.setUp();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ abstract contract CalculateMinimumFeeInWei_Integration_Test is Integration_Test

function test_GivenMinimumFeeZero() external givenPriceFeedAddressNotZero {
resetPrank(users.admin);
merkleBase.setMinimumFeeToZero();
merkleBase.lowerMinimumFee(0);
assertEq(merkleBase.calculateMinimumFeeInWei(), 0, "minimum fee in wei");
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.22 <0.9.0;

import { ISablierMerkleBase } from "src/interfaces/ISablierMerkleBase.sol";
import { Errors } from "src/libraries/Errors.sol";

import { Integration_Test } from "../../../../Integration.t.sol";

abstract contract LowerMinimumFee_Integration_Test is Integration_Test {
function test_RevertWhen_CallerNotFactoryAdmin() external {
resetPrank({ msgSender: users.eve });
vm.expectRevert(
abi.encodeWithSelector(Errors.SablierMerkleBase_CallerNotFactoryAdmin.selector, users.admin, users.eve)
);
merkleBase.lowerMinimumFee(MINIMUM_FEE - 1);
}

function test_RevertWhen_NewFeeNotLower() external whenCallerFactoryAdmin {
uint256 newFee = MINIMUM_FEE + 1;
resetPrank(users.admin);
vm.expectRevert(abi.encodeWithSelector(Errors.SablierMerkleBase_NewFeeNotLower.selector, MINIMUM_FEE, newFee));
merkleBase.lowerMinimumFee(newFee);
}

function test_WhenNewFeeNotZero() external whenCallerFactoryAdmin whenNewFeeLower {
uint256 newFee = MINIMUM_FEE - 1;
resetPrank(users.admin);
vm.expectEmit({ emitter: address(merkleBase) });
emit ISablierMerkleBase.LowerMinimumFee(users.admin, newFee, MINIMUM_FEE);
merkleBase.lowerMinimumFee(newFee);
assertEq(merkleBase.minimumFee(), newFee);
}

function test_WhenNewFeeZero() external whenCallerFactoryAdmin whenNewFeeLower {
uint256 newFee = 0;
resetPrank(users.admin);
vm.expectEmit({ emitter: address(merkleBase) });
emit ISablierMerkleBase.LowerMinimumFee(users.admin, newFee, MINIMUM_FEE);
merkleBase.lowerMinimumFee(newFee);
assertEq(merkleBase.minimumFee(), newFee);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
LowerMinimumFee_Integration_Test
├── when caller not factory admin
│ └── it should revert
└── when caller factory admin
├── when new fee not lower
│ └── it should revert
└── when new fee lower
├── when new fee not zero
│ ├── it should set minimum fee to new fee
│ └── it should emit event LowerMinimumFee
└── when new fee zero
├── it should set minimum fee to zero
└── it should emit event LowerMinimumFee

This file was deleted.

This file was deleted.

6 changes: 3 additions & 3 deletions tests/integration/concrete/campaign/vca/MerkleVCA.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { CollectFees_Integration_Test } from "./../shared/collect-fees/collectFe
import { GetFirstClaimTime_Integration_Test } from "./../shared/get-first-claim-time/getFirstClaimTime.t.sol";
import { HasClaimed_Integration_Test } from "./../shared/has-claimed/hasClaimed.t.sol";
import { HasExpired_Integration_Test } from "./../shared/has-expired/hasExpired.t.sol";
import { SetMinimumFeeToZero_Integration_Test } from "./../shared/set-minimum-fee-to-zero/setMinimumFeeToZero.t.sol";
import { LowerMinimumFee_Integration_Test } from "./../shared/lower-minimum-fee/lowerMinimumFee.t.sol";

/*//////////////////////////////////////////////////////////////////////////
NON-SHARED TESTS
Expand Down Expand Up @@ -75,9 +75,9 @@ contract HasExpired_MerkleVCA_Integration_Test is MerkleVCA_Integration_Shared_T
}
}

contract SetMinimumFeeToZero_MerkleVCA_Integration_Test is
contract LowerMinimumFee_MerkleVCA_Integration_Test is
MerkleVCA_Integration_Shared_Test,
SetMinimumFeeToZero_Integration_Test
LowerMinimumFee_Integration_Test
{
function setUp() public override(MerkleVCA_Integration_Shared_Test, Integration_Test) {
MerkleVCA_Integration_Shared_Test.setUp();
Expand Down
8 changes: 8 additions & 0 deletions tests/utils/Modifiers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ abstract contract Modifiers is EvmUtilsBase {
GIVEN
//////////////////////////////////////////////////////////////////////////*/

modifier whenCallerFactoryAdmin() {
_;
}

modifier givenCampaignNotExists() {
_;
}
Expand Down Expand Up @@ -95,6 +99,10 @@ abstract contract Modifiers is EvmUtilsBase {
_;
}

modifier whenNewFeeLower() {
_;
}

modifier whenNewFeeDoesNotExceedTheMaximumFee() {
_;
}
Expand Down

0 comments on commit fd96c70

Please sign in to comment.