diff --git a/tests/Base.t.sol b/tests/Base.t.sol index 905cb2c9..2ca3634d 100644 --- a/tests/Base.t.sol +++ b/tests/Base.t.sol @@ -10,10 +10,9 @@ import { ERC20Mock } from "./mocks/ERC20Mock.sol"; import { Assertions } from "./utils/Assertions.sol"; import { Modifiers } from "./utils/Modifiers.sol"; import { Users } from "./utils/Types.sol"; -import { Utils } from "./utils/Utils.sol"; import { Vars } from "./utils/Vars.sol"; -abstract contract Base_Test is Assertions, Modifiers, Test, Utils { +abstract contract Base_Test is Assertions, Modifiers, Test { /*////////////////////////////////////////////////////////////////////////// VARIABLES //////////////////////////////////////////////////////////////////////////*/ @@ -65,6 +64,9 @@ abstract contract Base_Test is Assertions, Modifiers, Test, Utils { users.recipient = createUser("recipient"); users.sender = createUser("sender"); + // Set the variables in Modifiers contract. + setVariables(users); + resetPrank(users.sender); // Warp to May 1, 2024 at 00:00 GMT to provide a more realistic testing environment. diff --git a/tests/integration/Integration.t.sol b/tests/integration/Integration.t.sol index 3b4c7711..de9e49ba 100644 --- a/tests/integration/Integration.t.sol +++ b/tests/integration/Integration.t.sol @@ -4,62 +4,22 @@ pragma solidity >=0.8.22; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ud21x18, UD21x18 } from "@prb/math/src/UD21x18.sol"; -import { Errors } from "src/libraries/Errors.sol"; -import { Broker, Flow } from "src/types/DataTypes.sol"; - import { Base_Test } from "../Base.t.sol"; /// @notice Common logic needed by all integration tests, both concrete and fuzz tests. abstract contract Integration_Test is Base_Test { - /*////////////////////////////////////////////////////////////////////////// - VARIABLES - //////////////////////////////////////////////////////////////////////////*/ - - Broker internal defaultBroker; - uint256 internal defaultStreamId; - uint256 internal nullStreamId = 420; - /*////////////////////////////////////////////////////////////////////////// SET-UP //////////////////////////////////////////////////////////////////////////*/ function setUp() public virtual override { Base_Test.setUp(); - - defaultBroker = broker(); - defaultStreamId = createDefaultStream(); - - // Simulate one month of streaming. - vm.warp({ newTimestamp: WARP_ONE_MONTH }); - } - - /*////////////////////////////////////////////////////////////////////////// - MODIFIERS - //////////////////////////////////////////////////////////////////////////*/ - - modifier givenBalanceNotZero() override { - // Deposit into the stream. - depositToDefaultStream(); - _; - } - - modifier whenCallerAdmin() override { - resetPrank({ msgSender: users.admin }); - _; } /*////////////////////////////////////////////////////////////////////////// HELPERS //////////////////////////////////////////////////////////////////////////*/ - function broker() public view returns (Broker memory) { - return Broker({ account: users.broker, fee: BROKER_FEE }); - } - - function createDefaultStream() internal returns (uint256) { - return createDefaultStream(usdc); - } - function createDefaultStream(IERC20 token_) internal returns (uint256) { return createDefaultStream(RATE_PER_SECOND, token_); } @@ -86,26 +46,6 @@ abstract contract Integration_Test is Base_Test { streamId = createDefaultStream(ratePerSecond, token); } - function defaultStream() internal view returns (Flow.Stream memory) { - return Flow.Stream({ - balance: 0, - snapshotTime: getBlockTimestamp(), - isStream: true, - isTransferable: TRANSFERABLE, - isVoided: false, - ratePerSecond: RATE_PER_SECOND, - snapshotDebtScaled: 0, - sender: users.sender, - token: usdc, - tokenDecimals: DECIMALS - }); - } - - function defaultStreamWithDeposit() internal view returns (Flow.Stream memory stream) { - stream = defaultStream(); - stream.balance = DEPOSIT_AMOUNT_6D; - } - function deposit(uint256 streamId, uint128 amount) internal { IERC20 token = flow.getToken(streamId); @@ -122,10 +62,6 @@ abstract contract Integration_Test is Base_Test { deposit(streamId, depositAmount); } - function depositToDefaultStream() internal { - deposit(defaultStreamId, DEPOSIT_AMOUNT_6D); - } - /// @dev Update the snapshot using `adjustRatePerSecond` and then warp block timestamp to it. function updateSnapshotTimeAndWarp(uint256 streamId) internal { resetPrank(users.sender); @@ -140,80 +76,4 @@ abstract contract Integration_Test is Base_Test { // Warp to the snapshot time. vm.warp({ newTimestamp: flow.getSnapshotTime(streamId) }); } - - /*////////////////////////////////////////////////////////////////////////// - COMMON-REVERT-TESTS - //////////////////////////////////////////////////////////////////////////*/ - - function expectRevert_CallerMaliciousThirdParty(bytes memory callData) internal { - resetPrank({ msgSender: users.eve }); - (bool success, bytes memory returnData) = address(flow).call(callData); - assertFalse(success, "malicious call success"); - assertEq( - returnData, - abi.encodeWithSelector(Errors.SablierFlow_Unauthorized.selector, defaultStreamId, users.eve), - "malicious call return data" - ); - } - - function expectRevert_CallerRecipient(bytes memory callData) internal { - resetPrank({ msgSender: users.recipient }); - (bool success, bytes memory returnData) = address(flow).call(callData); - assertFalse(success, "recipient call success"); - assertEq( - returnData, - abi.encodeWithSelector(Errors.SablierFlow_Unauthorized.selector, defaultStreamId, users.recipient), - "recipient call return data" - ); - } - - function expectRevert_CallerSender(bytes memory callData) internal { - resetPrank({ msgSender: users.sender }); - (bool success, bytes memory returnData) = address(flow).call(callData); - assertFalse(success, "sender call success"); - assertEq( - returnData, - abi.encodeWithSelector(Errors.SablierFlow_Unauthorized.selector, defaultStreamId, users.sender), - "sender call return data" - ); - } - - function expectRevert_DelegateCall(bytes memory callData) internal { - (bool success, bytes memory returnData) = address(flow).delegatecall(callData); - assertFalse(success, "delegatecall success"); - assertEq(returnData, abi.encodeWithSelector(Errors.DelegateCall.selector), "delegatecall return data"); - } - - function expectRevert_Null(bytes memory callData) internal { - (bool success, bytes memory returnData) = address(flow).call(callData); - assertFalse(success, "null call success"); - assertEq( - returnData, abi.encodeWithSelector(Errors.SablierFlow_Null.selector, nullStreamId), "null call return data" - ); - } - - function expectRevert_Voided(bytes memory callData) internal { - // Simulate the passage of time to accumulate uncovered debt for one month. - vm.warp({ newTimestamp: WARP_SOLVENCY_PERIOD + ONE_MONTH }); - flow.void(defaultStreamId); - - (bool success, bytes memory returnData) = address(flow).call(callData); - assertFalse(success, "voided call success"); - assertEq( - returnData, - abi.encodeWithSelector(Errors.SablierFlow_StreamVoided.selector, defaultStreamId), - "voided call return data" - ); - } - - function expectRevert_Paused(bytes memory callData) internal { - flow.pause(defaultStreamId); - (bool success, bytes memory returnData) = address(flow).call(callData); - assertFalse(success, "paused call success"); - assertEq( - returnData, - abi.encodeWithSelector(Errors.SablierFlow_StreamPaused.selector, defaultStreamId), - "paused call return data" - ); - } } diff --git a/tests/integration/concrete/Concrete.t.sol b/tests/integration/concrete/Concrete.t.sol new file mode 100644 index 00000000..95e65c8c --- /dev/null +++ b/tests/integration/concrete/Concrete.t.sol @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.22; + +import { Errors } from "src/libraries/Errors.sol"; +import { Broker, Flow } from "src/types/DataTypes.sol"; + +import { Integration_Test } from "../Integration.t.sol"; + +abstract contract Shared_Integration_Concrete_Test is Integration_Test { + /*////////////////////////////////////////////////////////////////////////// + VARIABLES + //////////////////////////////////////////////////////////////////////////*/ + + Broker internal defaultBroker; + uint256 internal defaultStreamId; + uint256 internal nullStreamId = 420; + + /*////////////////////////////////////////////////////////////////////////// + MODIFIERS + //////////////////////////////////////////////////////////////////////////*/ + + modifier givenBalanceNotZero() override { + // Deposit into the stream. + depositToDefaultStream(); + _; + } + + /*////////////////////////////////////////////////////////////////////////// + SET-UP + //////////////////////////////////////////////////////////////////////////*/ + + function setUp() public virtual override { + Integration_Test.setUp(); + + defaultBroker = Broker({ account: users.broker, fee: BROKER_FEE }); + defaultStreamId = createDefaultStream(); + + // Simulate one month of streaming. + vm.warp({ newTimestamp: WARP_ONE_MONTH }); + } + + /*////////////////////////////////////////////////////////////////////////// + HELPERS + //////////////////////////////////////////////////////////////////////////*/ + + function createDefaultStream() internal returns (uint256) { + return createDefaultStream(usdc); + } + + function defaultStream() internal view returns (Flow.Stream memory) { + return Flow.Stream({ + balance: 0, + snapshotTime: getBlockTimestamp(), + isStream: true, + isTransferable: TRANSFERABLE, + isVoided: false, + ratePerSecond: RATE_PER_SECOND, + snapshotDebtScaled: 0, + sender: users.sender, + token: usdc, + tokenDecimals: DECIMALS + }); + } + + function defaultStreamWithDeposit() internal view returns (Flow.Stream memory stream) { + stream = defaultStream(); + stream.balance = DEPOSIT_AMOUNT_6D; + } + + function depositToDefaultStream() internal { + deposit(defaultStreamId, DEPOSIT_AMOUNT_6D); + } + + /*////////////////////////////////////////////////////////////////////////// + COMMON-REVERT-TESTS + //////////////////////////////////////////////////////////////////////////*/ + + function expectRevert_CallerMaliciousThirdParty(bytes memory callData) internal { + resetPrank({ msgSender: users.eve }); + (bool success, bytes memory returnData) = address(flow).call(callData); + assertFalse(success, "malicious call success"); + assertEq( + returnData, + abi.encodeWithSelector(Errors.SablierFlow_Unauthorized.selector, defaultStreamId, users.eve), + "malicious call return data" + ); + } + + function expectRevert_CallerRecipient(bytes memory callData) internal { + resetPrank({ msgSender: users.recipient }); + (bool success, bytes memory returnData) = address(flow).call(callData); + assertFalse(success, "recipient call success"); + assertEq( + returnData, + abi.encodeWithSelector(Errors.SablierFlow_Unauthorized.selector, defaultStreamId, users.recipient), + "recipient call return data" + ); + } + + function expectRevert_CallerSender(bytes memory callData) internal { + resetPrank({ msgSender: users.sender }); + (bool success, bytes memory returnData) = address(flow).call(callData); + assertFalse(success, "sender call success"); + assertEq( + returnData, + abi.encodeWithSelector(Errors.SablierFlow_Unauthorized.selector, defaultStreamId, users.sender), + "sender call return data" + ); + } + + function expectRevert_DelegateCall(bytes memory callData) internal { + (bool success, bytes memory returnData) = address(flow).delegatecall(callData); + assertFalse(success, "delegatecall success"); + assertEq(returnData, abi.encodeWithSelector(Errors.DelegateCall.selector), "delegatecall return data"); + } + + function expectRevert_Null(bytes memory callData) internal { + (bool success, bytes memory returnData) = address(flow).call(callData); + assertFalse(success, "null call success"); + assertEq( + returnData, abi.encodeWithSelector(Errors.SablierFlow_Null.selector, nullStreamId), "null call return data" + ); + } + + function expectRevert_Voided(bytes memory callData) internal { + // Simulate the passage of time to accumulate uncovered debt for one month. + vm.warp({ newTimestamp: WARP_SOLVENCY_PERIOD + ONE_MONTH }); + flow.void(defaultStreamId); + + (bool success, bytes memory returnData) = address(flow).call(callData); + assertFalse(success, "voided call success"); + assertEq( + returnData, + abi.encodeWithSelector(Errors.SablierFlow_StreamVoided.selector, defaultStreamId), + "voided call return data" + ); + } + + function expectRevert_Paused(bytes memory callData) internal { + flow.pause(defaultStreamId); + (bool success, bytes memory returnData) = address(flow).call(callData); + assertFalse(success, "paused call success"); + assertEq( + returnData, + abi.encodeWithSelector(Errors.SablierFlow_StreamPaused.selector, defaultStreamId), + "paused call return data" + ); + } +} diff --git a/tests/integration/concrete/adjust-rate-per-second/adjustRatePerSecond.t.sol b/tests/integration/concrete/adjust-rate-per-second/adjustRatePerSecond.t.sol index 32529f3d..c17f49fc 100644 --- a/tests/integration/concrete/adjust-rate-per-second/adjustRatePerSecond.t.sol +++ b/tests/integration/concrete/adjust-rate-per-second/adjustRatePerSecond.t.sol @@ -8,9 +8,9 @@ import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; import { Errors } from "src/libraries/Errors.sol"; import { Flow } from "src/types/DataTypes.sol"; -import { Integration_Test } from "./../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "./../Concrete.t.sol"; -contract AdjustRatePerSecond_Integration_Concrete_Test is Integration_Test { +contract AdjustRatePerSecond_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertWhen_DelegateCall() external { bytes memory callData = abi.encodeCall(flow.adjustRatePerSecond, (defaultStreamId, RATE_PER_SECOND)); expectRevert_DelegateCall(callData); diff --git a/tests/integration/concrete/batch/batch.t.sol b/tests/integration/concrete/batch/batch.t.sol index d7d4ceb7..ad259432 100644 --- a/tests/integration/concrete/batch/batch.t.sol +++ b/tests/integration/concrete/batch/batch.t.sol @@ -6,13 +6,13 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ud21x18, UD21x18 } from "@prb/math/src/UD21x18.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; import { Errors } from "src/libraries/Errors.sol"; -import { Integration_Test } from "./../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "./../Concrete.t.sol"; -contract Batch_Integration_Concrete_Test is Integration_Test { +contract Batch_Integration_Concrete_Test is Shared_Integration_Concrete_Test { uint256[] internal defaultStreamIds; function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); defaultStreamIds.push(defaultStreamId); // Create a second stream diff --git a/tests/integration/concrete/collect-protocol-revenue/collectProtocolRevenue.t.sol b/tests/integration/concrete/collect-protocol-revenue/collectProtocolRevenue.t.sol index 32a07f9c..4b585339 100644 --- a/tests/integration/concrete/collect-protocol-revenue/collectProtocolRevenue.t.sol +++ b/tests/integration/concrete/collect-protocol-revenue/collectProtocolRevenue.t.sol @@ -6,13 +6,13 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ISablierFlowBase } from "src/interfaces/ISablierFlowBase.sol"; import { Errors } from "src/libraries/Errors.sol"; -import { Integration_Test } from "./../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "./../Concrete.t.sol"; -contract CollectProtocolRevenue_Integration_Concrete_Test is Integration_Test { +contract CollectProtocolRevenue_Integration_Concrete_Test is Shared_Integration_Concrete_Test { uint256 internal streamIdWithProtocolFee; function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); // Go back in time to create a stream with a protocol fee. vm.warp({ newTimestamp: OCT_1_2024 }); diff --git a/tests/integration/concrete/constructor.t.sol b/tests/integration/concrete/constructor.t.sol index f11c4613..dea91397 100644 --- a/tests/integration/concrete/constructor.t.sol +++ b/tests/integration/concrete/constructor.t.sol @@ -4,9 +4,9 @@ pragma solidity >=0.8.22; import { UD60x18 } from "@prb/math/src/UD60x18.sol"; import { SablierFlow } from "src/SablierFlow.sol"; -import { Integration_Test } from "../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "./Concrete.t.sol"; -contract Constructor_Integration_Concrete_Test is Integration_Test { +contract Constructor_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_Constructor() external { // Construct the contract. SablierFlow constructedFlow = new SablierFlow(users.admin, nftDescriptor); diff --git a/tests/integration/concrete/covered-debt-of/coveredDebtOf.t.sol b/tests/integration/concrete/covered-debt-of/coveredDebtOf.t.sol index efb6f9bf..2e962a55 100644 --- a/tests/integration/concrete/covered-debt-of/coveredDebtOf.t.sol +++ b/tests/integration/concrete/covered-debt-of/coveredDebtOf.t.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.22; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract CoveredDebtOf_Integration_Concrete_Test is Integration_Test { +contract CoveredDebtOf_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertGiven_Null() external { bytes memory callData = abi.encodeCall(flow.coveredDebtOf, nullStreamId); expectRevert_Null(callData); diff --git a/tests/integration/concrete/create-and-deposit/createAndDeposit.t.sol b/tests/integration/concrete/create-and-deposit/createAndDeposit.t.sol index 8e7ced75..2bcb31a4 100644 --- a/tests/integration/concrete/create-and-deposit/createAndDeposit.t.sol +++ b/tests/integration/concrete/create-and-deposit/createAndDeposit.t.sol @@ -7,9 +7,9 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; import { Flow } from "src/types/DataTypes.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract CreateAndDeposit_Integration_Concrete_Test is Integration_Test { +contract CreateAndDeposit_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertWhen_DelegateCall() external { bytes memory callData = abi.encodeCall( flow.createAndDeposit, diff --git a/tests/integration/concrete/create/create.t.sol b/tests/integration/concrete/create/create.t.sol index 9046f700..9b71d8b6 100644 --- a/tests/integration/concrete/create/create.t.sol +++ b/tests/integration/concrete/create/create.t.sol @@ -10,9 +10,9 @@ import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; import { Errors } from "src/libraries/Errors.sol"; import { Flow } from "src/types/DataTypes.sol"; import { ERC20Mock } from "./../../../mocks/ERC20Mock.sol"; -import { Integration_Test } from "./../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "./../Concrete.t.sol"; -contract Create_Integration_Concrete_Test is Integration_Test { +contract Create_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertWhen_DelegateCall() external { bytes memory callData = abi.encodeCall(flow.create, (users.sender, users.recipient, RATE_PER_SECOND, dai, TRANSFERABLE)); diff --git a/tests/integration/concrete/depletion-time-of/depletionTimeOf.t.sol b/tests/integration/concrete/depletion-time-of/depletionTimeOf.t.sol index aca40c87..b7f89f9d 100644 --- a/tests/integration/concrete/depletion-time-of/depletionTimeOf.t.sol +++ b/tests/integration/concrete/depletion-time-of/depletionTimeOf.t.sol @@ -4,9 +4,9 @@ pragma solidity >=0.8.22; import { UD21x18 } from "@prb/math/src/UD21x18.sol"; import { Errors } from "src/libraries/Errors.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "./../Concrete.t.sol"; -contract DepletionTimeOf_Integration_Concrete_Test is Integration_Test { +contract DepletionTimeOf_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertGiven_Null() external { bytes memory callData = abi.encodeCall(flow.depletionTimeOf, nullStreamId); expectRevert_Null(callData); diff --git a/tests/integration/concrete/deposit-and-pause/depositAndPause.t.sol b/tests/integration/concrete/deposit-and-pause/depositAndPause.t.sol index 19c4bfb6..fcf4f982 100644 --- a/tests/integration/concrete/deposit-and-pause/depositAndPause.t.sol +++ b/tests/integration/concrete/deposit-and-pause/depositAndPause.t.sol @@ -7,11 +7,11 @@ import { UD21x18 } from "@prb/math/src/UD21x18.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract DepositAndPause_Integration_Concrete_Test is Integration_Test { +contract DepositAndPause_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); // Advance the time past the solvency period so that there is uncovered debt. vm.warp({ newTimestamp: WARP_SOLVENCY_PERIOD + 1 days }); diff --git a/tests/integration/concrete/deposit-via-broker/depositViaBroker.t.sol b/tests/integration/concrete/deposit-via-broker/depositViaBroker.t.sol index 89f0fd66..f816fd94 100644 --- a/tests/integration/concrete/deposit-via-broker/depositViaBroker.t.sol +++ b/tests/integration/concrete/deposit-via-broker/depositViaBroker.t.sol @@ -8,9 +8,9 @@ import { ud } from "@prb/math/src/UD60x18.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; import { Errors } from "src/libraries/Errors.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract DepositViaBroker_Integration_Concrete_Test is Integration_Test { +contract DepositViaBroker_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertWhen_DelegateCall() external { bytes memory callData = abi.encodeCall( flow.depositViaBroker, diff --git a/tests/integration/concrete/deposit/deposit.t.sol b/tests/integration/concrete/deposit/deposit.t.sol index 2907217b..e2e99209 100644 --- a/tests/integration/concrete/deposit/deposit.t.sol +++ b/tests/integration/concrete/deposit/deposit.t.sol @@ -7,9 +7,9 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; import { Errors } from "src/libraries/Errors.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract Deposit_Integration_Concrete_Test is Integration_Test { +contract Deposit_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertWhen_DelegateCall() external { bytes memory callData = abi.encodeCall(flow.deposit, (defaultStreamId, DEPOSIT_AMOUNT_6D, users.sender, users.recipient)); diff --git a/tests/integration/concrete/getters/getters.t.sol b/tests/integration/concrete/getters/getters.t.sol index 912c8068..c5ad9505 100644 --- a/tests/integration/concrete/getters/getters.t.sol +++ b/tests/integration/concrete/getters/getters.t.sol @@ -2,10 +2,11 @@ pragma solidity >=0.8.22; import { ud21x18 } from "@prb/math/src/UD21x18.sol"; +import { Flow } from "src/types/DataTypes.sol"; -import { Integration_Test, Flow } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract Getters_Integration_Concrete_Test is Integration_Test { +contract Getters_Integration_Concrete_Test is Shared_Integration_Concrete_Test { /*////////////////////////////////////////////////////////////////////////// GET-BALANCE //////////////////////////////////////////////////////////////////////////*/ diff --git a/tests/integration/concrete/ongoing-debt-of/ongoingDebtScaledOf.t.sol b/tests/integration/concrete/ongoing-debt-of/ongoingDebtScaledOf.t.sol index fca5f92b..55d0e33d 100644 --- a/tests/integration/concrete/ongoing-debt-of/ongoingDebtScaledOf.t.sol +++ b/tests/integration/concrete/ongoing-debt-of/ongoingDebtScaledOf.t.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.22; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract OngoingDebtScaledOf_Integration_Concrete_Test is Integration_Test { +contract OngoingDebtScaledOf_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertGiven_Null() external { bytes memory callData = abi.encodeCall(flow.ongoingDebtScaledOf, nullStreamId); expectRevert_Null(callData); diff --git a/tests/integration/concrete/pause/pause.t.sol b/tests/integration/concrete/pause/pause.t.sol index 51588df6..664d6445 100644 --- a/tests/integration/concrete/pause/pause.t.sol +++ b/tests/integration/concrete/pause/pause.t.sol @@ -6,9 +6,9 @@ import { UD21x18 } from "@prb/math/src/UD21x18.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract Pause_Integration_Concrete_Test is Integration_Test { +contract Pause_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertWhen_DelegateCall() external { bytes memory callData = abi.encodeCall(flow.pause, (defaultStreamId)); expectRevert_DelegateCall(callData); diff --git a/tests/integration/concrete/recover/recover.t.sol b/tests/integration/concrete/recover/recover.t.sol index 9e512c51..5a8ea50f 100644 --- a/tests/integration/concrete/recover/recover.t.sol +++ b/tests/integration/concrete/recover/recover.t.sol @@ -4,13 +4,13 @@ pragma solidity >=0.8.22; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ISablierFlowBase } from "src/interfaces/ISablierFlowBase.sol"; import { Errors } from "src/libraries/Errors.sol"; -import { Integration_Test } from "./../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "./../Concrete.t.sol"; -contract Recover_Integration_Concrete_Test is Integration_Test { +contract Recover_Integration_Concrete_Test is Shared_Integration_Concrete_Test { uint256 internal surplusAmount = 1e6; function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); // Increase the flow contract balance in order to have a surplus. deal({ token: address(usdc), to: address(flow), give: surplusAmount }); diff --git a/tests/integration/concrete/refund-and-pause/refundAndPause.t.sol b/tests/integration/concrete/refund-and-pause/refundAndPause.t.sol index b7d25a32..7762cd6f 100644 --- a/tests/integration/concrete/refund-and-pause/refundAndPause.t.sol +++ b/tests/integration/concrete/refund-and-pause/refundAndPause.t.sol @@ -7,11 +7,11 @@ import { UD21x18 } from "@prb/math/src/UD21x18.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract RefundAndPause_Integration_Concrete_Test is Integration_Test { +contract RefundAndPause_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); depositToDefaultStream(); } diff --git a/tests/integration/concrete/refund-max/refundMax.t.sol b/tests/integration/concrete/refund-max/refundMax.t.sol index 97093e8a..21f3735c 100644 --- a/tests/integration/concrete/refund-max/refundMax.t.sol +++ b/tests/integration/concrete/refund-max/refundMax.t.sol @@ -6,11 +6,11 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract RefundMax_Integration_Concrete_Test is Integration_Test { +contract RefundMax_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); // Deposit to the default stream. depositToDefaultStream(); diff --git a/tests/integration/concrete/refund/refund.t.sol b/tests/integration/concrete/refund/refund.t.sol index d402d40d..1a9f0ae4 100644 --- a/tests/integration/concrete/refund/refund.t.sol +++ b/tests/integration/concrete/refund/refund.t.sol @@ -7,11 +7,11 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; import { Errors } from "src/libraries/Errors.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract Refund_Integration_Concrete_Test is Integration_Test { +contract Refund_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); // Deposit to the default stream. depositToDefaultStream(); diff --git a/tests/integration/concrete/refundable-amount-of/refundableAmountOf.t.sol b/tests/integration/concrete/refundable-amount-of/refundableAmountOf.t.sol index 35380387..167857ee 100644 --- a/tests/integration/concrete/refundable-amount-of/refundableAmountOf.t.sol +++ b/tests/integration/concrete/refundable-amount-of/refundableAmountOf.t.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.22; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract RefundableAmountOf_Integration_Concrete_Test is Integration_Test { +contract RefundableAmountOf_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertGiven_Null() external { bytes memory callData = abi.encodeCall(flow.refundableAmountOf, nullStreamId); expectRevert_Null(callData); diff --git a/tests/integration/concrete/restart-and-deposit/restartAndDeposit.t.sol b/tests/integration/concrete/restart-and-deposit/restartAndDeposit.t.sol index 571257a0..b687f824 100644 --- a/tests/integration/concrete/restart-and-deposit/restartAndDeposit.t.sol +++ b/tests/integration/concrete/restart-and-deposit/restartAndDeposit.t.sol @@ -7,11 +7,11 @@ import { UD21x18 } from "@prb/math/src/UD21x18.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract RestartAndDeposit_Integration_Concrete_Test is Integration_Test { +contract RestartAndDeposit_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); // Pause the stream for this test. flow.pause({ streamId: defaultStreamId }); diff --git a/tests/integration/concrete/restart/restart.t.sol b/tests/integration/concrete/restart/restart.t.sol index d836eddc..bd6aff0b 100644 --- a/tests/integration/concrete/restart/restart.t.sol +++ b/tests/integration/concrete/restart/restart.t.sol @@ -7,11 +7,11 @@ import { ud21x18, UD21x18 } from "@prb/math/src/UD21x18.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; import { Errors } from "src/libraries/Errors.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract Restart_Integration_Concrete_Test is Integration_Test { +contract Restart_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); // Pause the stream for this test. flow.pause({ streamId: defaultStreamId }); diff --git a/tests/integration/concrete/set-nft-descriptor/setNFTDescriptor.t.sol b/tests/integration/concrete/set-nft-descriptor/setNFTDescriptor.t.sol index 5d5e110a..a2bf67cd 100644 --- a/tests/integration/concrete/set-nft-descriptor/setNFTDescriptor.t.sol +++ b/tests/integration/concrete/set-nft-descriptor/setNFTDescriptor.t.sol @@ -5,9 +5,9 @@ import { IERC4906 } from "@openzeppelin/contracts/interfaces/IERC4906.sol"; import { FlowNFTDescriptor } from "src/FlowNFTDescriptor.sol"; import { ISablierFlowBase } from "src/interfaces/ISablierFlowBase.sol"; import { Errors } from "src/libraries/Errors.sol"; -import { Integration_Test } from "./../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "./../Concrete.t.sol"; -contract SetNFTDescriptor_Integration_Concrete_Test is Integration_Test { +contract SetNFTDescriptor_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertWhen_CallerNotAdmin() external { resetPrank({ msgSender: users.eve }); vm.expectRevert(abi.encodeWithSelector(Errors.CallerNotAdmin.selector, users.admin, users.eve)); diff --git a/tests/integration/concrete/set-protocol-fee/setProtocolFee.t.sol b/tests/integration/concrete/set-protocol-fee/setProtocolFee.t.sol index 917f0668..909bae0e 100644 --- a/tests/integration/concrete/set-protocol-fee/setProtocolFee.t.sol +++ b/tests/integration/concrete/set-protocol-fee/setProtocolFee.t.sol @@ -7,9 +7,9 @@ import { UD60x18, UNIT } from "@prb/math/src/UD60x18.sol"; import { ISablierFlowBase } from "src/interfaces/ISablierFlowBase.sol"; import { Errors } from "src/libraries/Errors.sol"; -import { Integration_Test } from "./../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "./../Concrete.t.sol"; -contract SetProtocolFee_Integration_Concrete_Test is Integration_Test { +contract SetProtocolFee_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertWhen_CallerNotAdmin() external { resetPrank({ msgSender: users.eve }); vm.expectRevert(abi.encodeWithSelector(Errors.CallerNotAdmin.selector, users.admin, users.eve)); diff --git a/tests/integration/concrete/status-of/statusOf.t.sol b/tests/integration/concrete/status-of/statusOf.t.sol index 692379e0..6006c364 100644 --- a/tests/integration/concrete/status-of/statusOf.t.sol +++ b/tests/integration/concrete/status-of/statusOf.t.sol @@ -3,11 +3,11 @@ pragma solidity >=0.8.22; import { Flow } from "src/types/DataTypes.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract StatusOf_Integration_Concrete_Test is Integration_Test { +contract StatusOf_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); depositToDefaultStream(); } diff --git a/tests/integration/concrete/token-uri/tokenURI.t.sol b/tests/integration/concrete/token-uri/tokenURI.t.sol index fcd922ae..c881bc3b 100644 --- a/tests/integration/concrete/token-uri/tokenURI.t.sol +++ b/tests/integration/concrete/token-uri/tokenURI.t.sol @@ -3,9 +3,9 @@ pragma solidity >=0.8.22; import { IERC721Errors } from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract TokenURI_Integration_Concrete_Test is Integration_Test { +contract TokenURI_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertGiven_NFTNotExist() external { vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, nullStreamId)); flow.tokenURI({ streamId: nullStreamId }); diff --git a/tests/integration/concrete/total-debt-of/totalDebtOf.t.sol b/tests/integration/concrete/total-debt-of/totalDebtOf.t.sol index cb8a5071..c3297575 100644 --- a/tests/integration/concrete/total-debt-of/totalDebtOf.t.sol +++ b/tests/integration/concrete/total-debt-of/totalDebtOf.t.sol @@ -3,9 +3,9 @@ pragma solidity >=0.8.22; import { ud21x18 } from "@prb/math/src/UD21x18.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract TotalDebtOf_Integration_Concrete_Test is Integration_Test { +contract TotalDebtOf_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertGiven_Null() external { bytes memory callData = abi.encodeCall(flow.totalDebtOf, nullStreamId); expectRevert_Null(callData); diff --git a/tests/integration/concrete/transfer-from/transferFrom.t.sol b/tests/integration/concrete/transfer-from/transferFrom.t.sol index 2097aeb4..52b47a8f 100644 --- a/tests/integration/concrete/transfer-from/transferFrom.t.sol +++ b/tests/integration/concrete/transfer-from/transferFrom.t.sol @@ -6,11 +6,11 @@ import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import { Errors } from "src/libraries/Errors.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract TransferFrom_Integration_Concrete_Test is Integration_Test { +contract TransferFrom_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function setUp() public virtual override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); // Prank the recipient for this test. resetPrank({ msgSender: users.recipient }); diff --git a/tests/integration/concrete/uncovered-debt-of/uncoveredDebtOf.t.sol b/tests/integration/concrete/uncovered-debt-of/uncoveredDebtOf.t.sol index 65a6c299..a76903e2 100644 --- a/tests/integration/concrete/uncovered-debt-of/uncoveredDebtOf.t.sol +++ b/tests/integration/concrete/uncovered-debt-of/uncoveredDebtOf.t.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.22; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract UncoveredDebtOf_Integration_Concrete_Test is Integration_Test { +contract UncoveredDebtOf_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); // Deposit into the stream. depositToDefaultStream(); diff --git a/tests/integration/concrete/void/void.t.sol b/tests/integration/concrete/void/void.t.sol index 44ca1ff3..3ea38b9e 100644 --- a/tests/integration/concrete/void/void.t.sol +++ b/tests/integration/concrete/void/void.t.sol @@ -5,11 +5,11 @@ import { IERC4906 } from "@openzeppelin/contracts/interfaces/IERC4906.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract Void_Integration_Concrete_Test is Integration_Test { +contract Void_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); // Deposit to the default stream. depositToDefaultStream(); diff --git a/tests/integration/concrete/withdraw-max/withdrawMax.t.sol b/tests/integration/concrete/withdraw-max/withdrawMax.t.sol index 74ce0824..9b43490b 100644 --- a/tests/integration/concrete/withdraw-max/withdrawMax.t.sol +++ b/tests/integration/concrete/withdraw-max/withdrawMax.t.sol @@ -6,11 +6,11 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract WithdrawMax_Integration_Concrete_Test is Integration_Test { +contract WithdrawMax_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); // Deposit to the default stream. depositToDefaultStream(); diff --git a/tests/integration/concrete/withdraw/withdraw.t.sol b/tests/integration/concrete/withdraw/withdraw.t.sol index 41899723..1b58370c 100644 --- a/tests/integration/concrete/withdraw/withdraw.t.sol +++ b/tests/integration/concrete/withdraw/withdraw.t.sol @@ -7,11 +7,11 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; import { Errors } from "src/libraries/Errors.sol"; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract Withdraw_Integration_Concrete_Test is Integration_Test { +contract Withdraw_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function setUp() public override { - Integration_Test.setUp(); + Shared_Integration_Concrete_Test.setUp(); depositToDefaultStream(); diff --git a/tests/integration/concrete/withdrawable-amount-of/withdrawableAmountOf.t.sol b/tests/integration/concrete/withdrawable-amount-of/withdrawableAmountOf.t.sol index 70d32a13..4ae116b1 100644 --- a/tests/integration/concrete/withdrawable-amount-of/withdrawableAmountOf.t.sol +++ b/tests/integration/concrete/withdrawable-amount-of/withdrawableAmountOf.t.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.22; -import { Integration_Test } from "../../Integration.t.sol"; +import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; -contract WithdrawableAmountOf_Integration_Concrete_Test is Integration_Test { +contract WithdrawableAmountOf_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_WithdrawableAmountOf() external givenNotNull givenBalanceNotZero { // Deposit into stream. depositToDefaultStream(); diff --git a/tests/integration/fuzz/depletionTimeOf.t.sol b/tests/integration/fuzz/depletionTimeOf.t.sol index 270ba2ac..0081a142 100644 --- a/tests/integration/fuzz/depletionTimeOf.t.sol +++ b/tests/integration/fuzz/depletionTimeOf.t.sol @@ -10,7 +10,15 @@ contract DepletionTimeOf_Integration_Fuzz_Test is Shared_Integration_Fuzz_Test { /// /// Given enough runs, all of the following scenarios should be fuzzed: /// - Multiple streams, each with different rate per second and decimals. - function testFuzz_DepletionTimeOf(uint256 streamId, uint8 decimals) external givenNotNull givenPaused { + function testFuzz_DepletionTimeOf( + uint256 streamId, + uint8 decimals + ) + external + givenNotNull + givenPaused + givenBalanceNotZero + { (streamId, decimals,) = useFuzzedStreamOrCreate(streamId, decimals); // Calculate the solvency period based on the stream deposit. diff --git a/tests/utils/Modifiers.sol b/tests/utils/Modifiers.sol index 694b8a49..b75679ee 100644 --- a/tests/utils/Modifiers.sol +++ b/tests/utils/Modifiers.sol @@ -1,7 +1,20 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity >=0.8.22; -abstract contract Modifiers { +import { Users } from "./Types.sol"; +import { Utils } from "./Utils.sol"; + +abstract contract Modifiers is Utils { + /*////////////////////////////////////////////////////////////////////////// + VARIABLES + //////////////////////////////////////////////////////////////////////////*/ + + Users private users; + + function setVariables(Users memory _users) public { + users = _users; + } + /*////////////////////////////////////////////////////////////////////////// COMMON //////////////////////////////////////////////////////////////////////////*/ @@ -22,7 +35,8 @@ abstract contract Modifiers { _; } - modifier whenCallerAdmin() virtual { + modifier whenCallerAdmin() { + resetPrank({ msgSender: users.admin }); _; }