Skip to content

Commit

Permalink
test(core): refactor integration tests for core
Browse files Browse the repository at this point in the history
  • Loading branch information
smol-ninja committed Nov 6, 2024
1 parent 4ef5bfb commit 80dbae3
Show file tree
Hide file tree
Showing 131 changed files with 1,797 additions and 2,159 deletions.
12 changes: 6 additions & 6 deletions benchmark/BatchLockup.Gas.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ contract BatchLockup_Gas_Test is Benchmark_Test {
//////////////////////////////////////////////////////////////////////////*/

function gasCreateWithDurationsLD(uint256 batchSize, uint256 segmentsCount) internal {
LockupDynamic.CreateWithDurations memory createParams = defaults.createWithDurationsBrokerNullLD();
LockupDynamic.CreateWithDurations memory createParams = defaults.createWithDurationsBrokerNull();
createParams.totalAmount = uint128(AMOUNT_PER_ITEM * segmentsCount);
createParams.segments = _generateSegmentsWithDuration(segmentsCount);
BatchLockup.CreateWithDurationsLD[] memory params = BatchLockupBuilder.fillBatch(createParams, batchSize);
Expand All @@ -82,7 +82,7 @@ contract BatchLockup_Gas_Test is Benchmark_Test {
}

function gasCreateWithTimestampsLD(uint256 batchSize, uint256 segmentsCount) internal {
LockupDynamic.CreateWithTimestamps memory createParams = defaults.createWithTimestampsBrokerNullLD();
LockupDynamic.CreateWithTimestamps memory createParams = defaults.createWithTimestampsBrokerNull();
createParams.startTime = getBlockTimestamp();
createParams.totalAmount = uint128(AMOUNT_PER_ITEM * segmentsCount);
createParams.segments = _generateSegments(segmentsCount);
Expand All @@ -108,7 +108,7 @@ contract BatchLockup_Gas_Test is Benchmark_Test {

function gasCreateWithDurationsLL(uint256 batchSize) internal {
BatchLockup.CreateWithDurationsLL[] memory params =
BatchLockupBuilder.fillBatch({ params: defaults.createWithDurationsBrokerNullLL(), batchSize: batchSize });
BatchLockupBuilder.fillBatch({ params: defaults.createWithDurationsBrokerNull(), batchSize: batchSize });

uint256 initialGas = gasleft();
batchLockup.createWithDurationsLL(lockupLinear, dai, params);
Expand All @@ -124,7 +124,7 @@ contract BatchLockup_Gas_Test is Benchmark_Test {

function gasCreateWithTimestampsLL(uint256 batchSize) internal {
BatchLockup.CreateWithTimestampsLL[] memory params =
BatchLockupBuilder.fillBatch({ params: defaults.createWithTimestampsBrokerNullLL(), batchSize: batchSize });
BatchLockupBuilder.fillBatch({ params: defaults.createWithTimestampsBrokerNull(), batchSize: batchSize });

uint256 initialGas = gasleft();
batchLockup.createWithTimestampsLL(lockupLinear, dai, params);
Expand All @@ -139,7 +139,7 @@ contract BatchLockup_Gas_Test is Benchmark_Test {
}

function gasCreateWithDurationsLT(uint256 batchSize, uint256 tranchesCount) internal {
LockupTranched.CreateWithDurations memory createParams = defaults.createWithDurationsBrokerNullLT();
LockupTranched.CreateWithDurations memory createParams = defaults.createWithDurationsBrokerNull();
createParams.totalAmount = uint128(AMOUNT_PER_ITEM * tranchesCount);
createParams.tranches = _generateTranchesWithDuration(tranchesCount);
BatchLockup.CreateWithDurationsLT[] memory params = BatchLockupBuilder.fillBatch(createParams, batchSize);
Expand All @@ -163,7 +163,7 @@ contract BatchLockup_Gas_Test is Benchmark_Test {
}

function gasCreateWithTimestampsLT(uint256 batchSize, uint256 tranchesCount) internal {
LockupTranched.CreateWithTimestamps memory createParams = defaults.createWithTimestampsBrokerNullLT();
LockupTranched.CreateWithTimestamps memory createParams = defaults.createWithTimestampsBrokerNull();
createParams.startTime = getBlockTimestamp();
createParams.totalAmount = uint128(AMOUNT_PER_ITEM * tranchesCount);
createParams.tranches = _generateTranches(tranchesCount);
Expand Down
2 changes: 1 addition & 1 deletion benchmark/LockupTranched.Gas.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ contract LockupTranched_Gas_Test is Benchmark_Test {

uint128 depositAmount = AMOUNT_PER_SEGMENT * totalTranches;

params = defaults.createWithDurationsLT();
params = defaults.createWithDurations();
params.broker.fee = brokerFee;
params.totalAmount = _calculateTotalAmount(depositAmount, brokerFee);
params.tranches = tranches_;
Expand Down
4 changes: 1 addition & 3 deletions test/core/fork/LockupDynamic.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,7 @@ abstract contract LockupDynamic_Fork_Test is Fork_Test {
vars.isCancelable = vars.isSettled ? false : true;

// Assert that the stream has been created.
assertEq(lockup.getDepositedAmount(vars.streamId), vars.createAmounts.deposit);
assertEq(lockup.getRefundedAmount(vars.streamId), 0);
assertEq(lockup.getWithdrawnAmount(vars.streamId), 0);
assertEq(lockup.getDepositedAmount(vars.streamId), vars.createAmounts.deposit, "depositedAmount");
assertEq(lockup.getAsset(vars.streamId), FORK_ASSET, "asset");
assertEq(lockup.getEndTime(vars.streamId), vars.timestamps.end, "endTime");
assertEq(lockup.isCancelable(vars.streamId), vars.isCancelable, "isCancelable");
Expand Down
6 changes: 2 additions & 4 deletions test/core/fork/LockupLinear.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,9 @@ abstract contract LockupLinear_Fork_Test is Fork_Test {
vars.isCancelable = vars.isSettled ? false : true;

// Assert that the stream has been created.
assertEq(lockup.getDepositedAmount(vars.streamId), vars.createAmounts.deposit);
assertEq(lockup.getRefundedAmount(vars.streamId), 0);
assertEq(lockup.getWithdrawnAmount(vars.streamId), 0);
assertEq(lockup.getDepositedAmount(vars.streamId), vars.createAmounts.deposit, "depositedAmount");
assertEq(lockup.getAsset(vars.streamId), FORK_ASSET, "asset");
assertEq(lockup.getCliff(vars.streamId), params.timestamps.cliff, "cliffTime");
assertEq(lockup.getCliffTime(vars.streamId), params.timestamps.cliff, "cliffTime");
assertEq(lockup.getEndTime(vars.streamId), params.timestamps.end, "endTime");
assertEq(lockup.isCancelable(vars.streamId), vars.isCancelable, "isCancelable");
assertEq(lockup.isDepleted(vars.streamId), false, "isDepleted");
Expand Down
4 changes: 1 addition & 3 deletions test/core/fork/LockupTranched.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,7 @@ abstract contract LockupTranched_Fork_Test is Fork_Test {
vars.isCancelable = vars.isSettled ? false : true;

// Assert that the stream has been created.
assertEq(lockup.getDepositedAmount(vars.streamId), vars.createAmounts.deposit);
assertEq(lockup.getRefundedAmount(vars.streamId), 0);
assertEq(lockup.getWithdrawnAmount(vars.streamId), 0);
assertEq(lockup.getDepositedAmount(vars.streamId), vars.createAmounts.deposit, "depositedAmount");
assertEq(lockup.getAsset(vars.streamId), FORK_ASSET, "asset");
assertEq(lockup.getEndTime(vars.streamId), vars.timestamps.end, "endTime");
assertEq(lockup.isCancelable(vars.streamId), vars.isCancelable, "isCancelable");
Expand Down
4 changes: 3 additions & 1 deletion test/core/fork/NFTDescriptor.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,9 @@ contract NFTDescriptor_Fork_Test is Fork_Test {
/// Given enough fuzz runs, all the following scenarios will be fuzzed:
/// - Multiple values of streamId.
function testForkFuzz_TokenURI_Lockup_v1_3_0(uint256 streamId) external loadDeployments_v1_3_0 {
streamId = _bound(streamId, 1, lockup.nextStreamId() - 1);
// TODO: Uncomment it after the deployment.
// streamId = _bound(streamId, 1, lockup.nextStreamId() - 1);
streamId = 1;

// Set the new NFT descriptor for the previous version of Lockup.
resetPrank({ msgSender: lockup.admin() });
Expand Down
75 changes: 19 additions & 56 deletions test/core/integration/Integration.t.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.22 <0.9.0;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import { ISablierLockup } from "src/core/interfaces/ISablierLockup.sol";
import { Errors } from "src/core/libraries/Errors.sol";
import { Broker } from "src/core/types/DataTypes.sol";

import { Base_Test } from "../../Base.t.sol";
import {
Expand All @@ -22,17 +18,32 @@ abstract contract Integration_Test is Base_Test {
VARIABLES
//////////////////////////////////////////////////////////////////////////*/

// Various stream IDs to be used across the tests.
// Default stream ID.
uint256 internal defaultStreamId;
// A stream ID with a different sender and recipient.
uint256 internal differentSenderRecipientStreamId;
// A stream ID with an early end time.
uint256 internal earlyEndtimeStreamId;
// A stream ID with the same sender and recipient.
uint256 internal identicalSenderRecipientStreamId;
// A non-cancelable stream ID.
uint256 internal notCancelableStreamId;
// A non-transferable stream ID.
uint256 internal notTransferableStreamId;
// A stream with a recipient contract that implements {ISablierLockupRecipient}.
uint256 internal recipientContractStreamId;
// A stream with a recipient contract that returns invalid selector bytes on the hook call.
uint256 internal recipientInvalidSelectorStreamId;
// A stream with a reentrant contract as the recipient.
uint256 internal recipientReentrantStreamId;
// Astream with a reverting contract as the stream's recipient.
uint256 internal recipientRevertStreamId;

/*//////////////////////////////////////////////////////////////////////////
TEST CONTRACTS
//////////////////////////////////////////////////////////////////////////*/

/// @dev A test contract that is meant to be overridden by the implementing contract, which will be
/// either {SablierLockupDynamic}, {SablierLockupLinear} or {SablierLockupTranched}.
ISablierLockup internal lockup;

RecipientInterfaceIDIncorrect internal recipientInterfaceIDIncorrect;
RecipientInterfaceIDMissing internal recipientInterfaceIDMissing;
RecipientInvalidSelector internal recipientInvalidSelector;
Expand Down Expand Up @@ -67,52 +78,4 @@ abstract contract Integration_Test is Base_Test {
assertFalse(success, "delegatecall success");
assertEq(returnData, abi.encodeWithSelector(Errors.DelegateCall.selector), "delegatecall return data");
}

/*//////////////////////////////////////////////////////////////////////////
HELPERS
//////////////////////////////////////////////////////////////////////////*/

/// @dev Creates the default stream.
function createDefaultStream() internal virtual returns (uint256 streamId);

/// @dev Creates the default stream but make it not cancelable.
function createDefaultStreamNotCancelable() internal virtual returns (uint256 streamId);

/// @dev Creates the default stream with the NFT transfer disabled.
function createDefaultStreamNotTransferable() internal virtual returns (uint256 streamId);

/// @dev Creates the default stream with the provided address.
function createDefaultStreamWithAsset(IERC20 asset) internal virtual returns (uint256 streamId);

/// @dev Creates the default stream with the provided broker.
function createDefaultStreamWithBroker(Broker memory broker) internal virtual returns (uint256 streamId);

/// @dev Creates the default stream with the provided end time.
function createDefaultStreamWithEndTime(uint40 endTime) internal virtual returns (uint256 streamId);

/// @dev Creates the default stream with the provided user as the recipient and the sender.
function createDefaultStreamWithIdenticalUsers(address user) internal returns (uint256 streamId) {
return createDefaultStreamWithUsers({ recipient: user, sender: user });
}

/// @dev Creates the default stream with the provided recipient.
function createDefaultStreamWithRecipient(address recipient) internal virtual returns (uint256 streamId);

/// @dev Creates the default stream with the provided sender.
function createDefaultStreamWithSender(address sender) internal virtual returns (uint256 streamId);

/// @dev Creates the default stream with the provided start time.
function createDefaultStreamWithStartTime(uint40 startTime) internal virtual returns (uint256 streamId);

/// @dev Creates the default stream with the provided total amount.
function createDefaultStreamWithTotalAmount(uint128 totalAmount) internal virtual returns (uint256 streamId);

/// @dev Creates the default stream with the provided sender and recipient.
function createDefaultStreamWithUsers(
address recipient,
address sender
)
internal
virtual
returns (uint256 streamId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,47 @@ pragma solidity >=0.8.22 <0.9.0;
import { UD60x18 } from "@prb/math/src/UD60x18.sol";

import { IAdminable } from "src/core/interfaces/IAdminable.sol";
import { SablierLockupLinear } from "src/core/SablierLockupLinear.sol";
import { SablierLockup } from "src/core/SablierLockup.sol";

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

contract Constructor_LockupLinear_Integration_Concrete_Test is LockupLinear_Integration_Shared_Test {
contract Constructor_Integration_Concrete_Test is Integration_Test {
function test_Constructor() external {
// Expect the relevant event to be emitted.
vm.expectEmit();
emit IAdminable.TransferAdmin({ oldAdmin: address(0), newAdmin: users.admin });

// Construct the contract.
SablierLockupLinear constructedLockupLinear =
new SablierLockupLinear({ initialAdmin: users.admin, initialNFTDescriptor: nftDescriptor });
SablierLockup constructedLockup = new SablierLockup({
initialAdmin: users.admin,
initialNFTDescriptor: nftDescriptor,
maxCount: defaults.MAX_COUNT()
});

// {SablierLockup.constant}
UD60x18 actualMaxBrokerFee = constructedLockupLinear.MAX_BROKER_FEE();
UD60x18 actualMaxBrokerFee = constructedLockup.MAX_BROKER_FEE();
UD60x18 expectedMaxBrokerFee = UD60x18.wrap(0.1e18);
assertEq(actualMaxBrokerFee, expectedMaxBrokerFee, "MAX_BROKER_FEE");

// {SablierLockup.constructor}
address actualAdmin = constructedLockupLinear.admin();
address actualAdmin = constructedLockup.admin();
address expectedAdmin = users.admin;
assertEq(actualAdmin, expectedAdmin, "admin");

uint256 actualStreamId = constructedLockupLinear.nextStreamId();
uint256 actualStreamId = constructedLockup.nextStreamId();
uint256 expectedStreamId = 1;
assertEq(actualStreamId, expectedStreamId, "nextStreamId");

address actualNFTDescriptor = address(constructedLockupLinear.nftDescriptor());
address actualNFTDescriptor = address(constructedLockup.nftDescriptor());
address expectedNFTDescriptor = address(nftDescriptor);
assertEq(actualNFTDescriptor, expectedNFTDescriptor, "nftDescriptor");

// {SablierLockup.supportsInterface}
assertTrue(constructedLockupLinear.supportsInterface(0x49064906), "ERC-4906 interface ID");
assertTrue(constructedLockup.supportsInterface(0x49064906), "ERC-4906 interface ID");

// {SablierLockup.constructor}
uint256 actualMaxCount = constructedLockup.MAX_COUNT();
uint256 expectedMaxCount = defaults.MAX_COUNT();
assertEq(actualMaxCount, expectedMaxCount, "MAX_COUNT");
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.22 <0.9.0;

import { ISablierLockup } from "src/core/interfaces/ISablierLockup.sol";
import { ISablierLockupBase } from "src/core/interfaces/ISablierLockupBase.sol";
import { Errors } from "src/core/libraries/Errors.sol";

import { Integration_Test } from "../../../Integration.t.sol";
Expand All @@ -18,7 +18,7 @@ abstract contract AllowToHook_Integration_Concrete_Test is Integration_Test {

function test_RevertWhen_ProvidedAddressNotContract() external whenCallerAdmin {
address eoa = vm.addr({ privateKey: 1 });
vm.expectRevert(abi.encodeWithSelector(Errors.SablierLockup_AllowToHookZeroCodeSize.selector, eoa));
vm.expectRevert(abi.encodeWithSelector(Errors.SablierLockupBase_AllowToHookZeroCodeSize.selector, eoa));
lockup.allowToHook(eoa);
}

Expand All @@ -30,7 +30,7 @@ abstract contract AllowToHook_Integration_Concrete_Test is Integration_Test {
// Incorrect interface ID.
address recipient = address(recipientInterfaceIDIncorrect);
vm.expectRevert(
abi.encodeWithSelector(Errors.SablierLockup_AllowToHookUnsupportedInterface.selector, recipient)
abi.encodeWithSelector(Errors.SablierLockupBase_AllowToHookUnsupportedInterface.selector, recipient)
);
lockup.allowToHook(recipient);

Expand All @@ -43,7 +43,7 @@ abstract contract AllowToHook_Integration_Concrete_Test is Integration_Test {
function test_WhenProvidedAddressReturnsInterfaceId() external whenCallerAdmin whenProvidedAddressContract {
// It should emit a {AllowToHook} event.
vm.expectEmit({ emitter: address(lockup) });
emit ISablierLockup.AllowToHook(users.admin, address(recipientGood));
emit ISablierLockupBase.AllowToHook(users.admin, address(recipientGood));

// Allow the provided address to hook.
lockup.allowToHook(address(recipientGood));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ abstract contract Batch_Integration_Concrete_Test is Integration_Test {
calls[0] = abi.encodeCall(lockup.getDepositedAmount, (nonExistentStreamId));

bytes memory expectedRevertData = abi.encodeWithSelector(
Errors.BatchError.selector, abi.encodeWithSelector(Errors.SablierLockup_Null.selector, nonExistentStreamId)
Errors.BatchError.selector,
abi.encodeWithSelector(Errors.SablierLockupBase_Null.selector, nonExistentStreamId)
);

vm.expectRevert(expectedRevertData);
Expand Down
Loading

0 comments on commit 80dbae3

Please sign in to comment.