Skip to content
This repository was archived by the owner on Mar 26, 2025. It is now read-only.
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
2 changes: 1 addition & 1 deletion lib/prb-test
Submodule prb-test updated 3 files
+7 −0 CHANGELOG.md
+1 −1 package.json
+20 −0 src/Vm.sol
103 changes: 63 additions & 40 deletions test/Base.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ abstract contract Base_Test is Assertions, StdCheats {
//////////////////////////////////////////////////////////////////////////*/

function setUp() public virtual {
// Create users for testing.
users.admin = createUser("Admin");
users.broker = createUser("Broker");
users.recipient = createUser("Recipient");
Expand Down Expand Up @@ -250,62 +249,86 @@ abstract contract Base_Test is Assertions, StdCheats {
vm.expectCall({ callee: address(linear), data: abi.encodeCall(ISablierV2LockupLinear.createWithRange, (params)) });
}

/// @dev Expects multiple calls to {SablierV2LockupDynamic.createWithMilestones}.
function expectMultipleCallsToCreateWithDeltas(LockupDynamic.CreateWithDeltas memory params) internal {
for (uint256 i = 0; i < defaults.BATCH_SIZE(); ++i) {
expectCallToCreateWithDeltas(params);
}
/// @dev Expects a call to {IERC20.transfer}.
function expectCallToTransfer(address to, uint256 amount) internal {
vm.expectCall({ callee: address(dai), data: abi.encodeCall(IERC20.transfer, (to, amount)) });
}

/// @dev Expects multiple calls to {ISablierV2LockupLinear.createWithDurations}.
function expectMultipleCallsToCreateWithDurations(LockupLinear.CreateWithDurations memory params) internal {
for (uint256 i = 0; i < defaults.BATCH_SIZE(); ++i) {
expectCallToCreateWithDurations(params);
}
/// @dev Expects a call to {IERC20.transferFrom}.
function expectCallToTransferFrom(address from, address to, uint256 amount) internal {
vm.expectCall({ callee: address(dai), data: abi.encodeCall(IERC20.transferFrom, (from, to, amount)) });
}

/// @dev Expects multiple calls to {SablierV2LockupDynamic.createWithMilestones}.
function expectMultipleCallsToCreateWithMilestones(LockupDynamic.CreateWithMilestones memory params) internal {
for (uint256 i = 0; i < defaults.BATCH_SIZE(); ++i) {
expectCallToCreateWithMilestones(params);
}
/// @dev Expects a call to {IERC20.transferFrom}.
function expectCallToTransferFrom(address asset, address from, address to, uint256 amount) internal {
vm.expectCall({ callee: asset, data: abi.encodeCall(IERC20.transferFrom, (from, to, amount)) });
}

/// @dev Expects multiple calls to {SablierV2LockupLinear.createWithRange}.
function expectMultipleCallsToCreateWithRange(LockupLinear.CreateWithRange memory params) internal {
for (uint256 i = 0; i < defaults.BATCH_SIZE(); ++i) {
expectCallToCreateWithRange(params);
}
/// @dev Expects multiple calls to {ISablierV2LockupDynamic.createWithMilestones}.
function expectMultipleCallsToCreateWithDeltas(
uint64 count,
LockupDynamic.CreateWithDeltas memory params
)
internal
{
vm.expectCall({
callee: address(dynamic),
count: uint64(count),
data: abi.encodeCall(ISablierV2LockupDynamic.createWithDeltas, (params))
});
}

/// @dev Expects multiple calls to the `transfer` function of the default ERC-20 contract.
function expectMultipleCallsToTransfer(address to, uint256 amount) internal {
for (uint256 i = 0; i < defaults.BATCH_SIZE(); ++i) {
expectCallToTransfer(to, amount);
}
/// @dev Expects multiple calls to {ISablierV2LockupLinear.createWithDurations}.
function expectMultipleCallsToCreateWithDurations(
uint64 count,
LockupLinear.CreateWithDurations memory params
)
internal
{
vm.expectCall({
callee: address(linear),
count: uint64(count),
data: abi.encodeCall(ISablierV2LockupLinear.createWithDurations, (params))
});
}

/// @dev Expects multiple calls to the `transferFrom` function of the default ERC-20 contract.
function expectMultipleCallsToTransferFrom(address from, address to, uint256 amount) internal {
for (uint256 i = 0; i < defaults.BATCH_SIZE(); ++i) {
expectCallToTransferFrom(from, to, amount);
}
/// @dev Expects multiple calls to {ISablierV2LockupDynamic.createWithMilestones}.
function expectMultipleCallsToCreateWithMilestones(
uint64 count,
LockupDynamic.CreateWithMilestones memory params
)
internal
{
vm.expectCall({
callee: address(dynamic),
count: uint64(count),
data: abi.encodeCall(ISablierV2LockupDynamic.createWithMilestones, (params))
});
}

/// @dev Expects a call to the `transfer` function of the default ERC-20 contract.
function expectCallToTransfer(address to, uint256 amount) internal {
vm.expectCall({ callee: address(dai), data: abi.encodeCall(IERC20.transfer, (to, amount)) });
/// @dev Expects multiple calls to {ISablierV2LockupLinear.createWithRange}.
function expectMultipleCallsToCreateWithRange(uint64 count, LockupLinear.CreateWithRange memory params) internal {
vm.expectCall({
callee: address(linear),
count: uint64(count),
data: abi.encodeCall(ISablierV2LockupLinear.createWithRange, (params))
});
}

/// @dev Expects a call to the `transferFrom` function of the default ERC-20 contract.
function expectCallToTransferFrom(address from, address to, uint256 amount) internal {
vm.expectCall({ callee: address(dai), data: abi.encodeCall(IERC20.transferFrom, (from, to, amount)) });
/// @dev Expects multiple calls to {IERC20.transfer}.
function expectMultipleCallsToTransfer(uint64 count, address to, uint256 amount) internal {
vm.expectCall({ callee: address(dai), count: uint64(count), data: abi.encodeCall(IERC20.transfer, (to, amount)) });
}

/// @dev Expects a call to the `transferFrom` function of the provided ERC-20 contract.
function expectCallToTransferFrom(address asset, address from, address to, uint256 amount) internal {
vm.expectCall({ callee: asset, data: abi.encodeCall(IERC20.transferFrom, (from, to, amount)) });
/// @dev Expects multiple calls to {IERC20.transferFrom}.
function expectMultipleCallsToTransferFrom(uint64 count, address from, address to, uint256 amount) internal {
vm.expectCall({
callee: address(dai),
count: uint64(count),
data: abi.encodeCall(IERC20.transferFrom, (from, to, amount))
});
}

/*//////////////////////////////////////////////////////////////////////////
PERMIT2
//////////////////////////////////////////////////////////////////////////*/
Expand Down
12 changes: 10 additions & 2 deletions test/unit/batch-cancel-multiple/batchCancelMultiple.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,16 @@ contract BatchCancelMultiple_Unit_Test is Unit_Test {

// Asset flow: Sablier → proxy → proxy owner
// Expects transfers from the Sablier contracts to the proxy, and then from the proxy to the proxy owner.
expectMultipleCallsToTransfer({ to: address(proxy), amount: defaults.REFUND_AMOUNT() });
expectMultipleCallsToTransfer({ to: address(proxy), amount: defaults.REFUND_AMOUNT() });
expectMultipleCallsToTransfer({
count: defaults.BATCH_SIZE(),
to: address(proxy),
amount: defaults.REFUND_AMOUNT()
});
expectMultipleCallsToTransfer({
count: defaults.BATCH_SIZE(),
to: address(proxy),
amount: defaults.REFUND_AMOUNT()
});
expectCallToTransfer({ to: users.sender.addr, amount: 2 * defaults.BATCH_SIZE() * defaults.REFUND_AMOUNT() });

// ABI encode the parameters and call the function via the proxy.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ contract BatchCreateWithDeltas_Unit_Test is Unit_Test {
// Asset flow: proxy owner → proxy → Sablier
// Expect transfers from the proxy owner to the proxy, and then from the proxy to the Sablier contract.
expectCallToTransferFrom({ from: users.sender.addr, to: address(proxy), amount: defaults.TRANSFER_AMOUNT() });
expectMultipleCallsToCreateWithDeltas({ params: defaults.createWithDeltas() });
expectMultipleCallsToCreateWithDeltas({ count: defaults.BATCH_SIZE(), params: defaults.createWithDeltas() });
expectMultipleCallsToTransferFrom({
count: defaults.BATCH_SIZE(),
from: address(proxy),
to: address(dynamic),
amount: defaults.PER_STREAM_AMOUNT()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ contract BatchCreateWithDurations_Unit_Test is Unit_Test {
// Asset flow: proxy owner → proxy → Sablier
// Expect transfers from the proxy owner to the proxy, and then from the proxy to the Sablier contract.
expectCallToTransferFrom({ from: users.sender.addr, to: address(proxy), amount: defaults.TRANSFER_AMOUNT() });
expectMultipleCallsToCreateWithDurations({ params: defaults.createWithDurations() });
expectMultipleCallsToCreateWithDurations({ count: defaults.BATCH_SIZE(), params: defaults.createWithDurations() });
expectMultipleCallsToTransferFrom({
count: defaults.BATCH_SIZE(),
from: address(proxy),
to: address(linear),
amount: defaults.PER_STREAM_AMOUNT()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ contract BatchCreateWithMilestones_Unit_Test is Unit_Test {
// Asset flow: proxy owner → proxy → Sablier
// Expect transfers from the proxy owner to the proxy, and then from the proxy to the Sablier contract.
expectCallToTransferFrom({ from: users.sender.addr, to: address(proxy), amount: defaults.TRANSFER_AMOUNT() });
expectMultipleCallsToCreateWithMilestones({ params: defaults.createWithMilestones() });
expectMultipleCallsToCreateWithMilestones({
count: defaults.BATCH_SIZE(),
params: defaults.createWithMilestones()
});
expectMultipleCallsToTransferFrom({
count: defaults.BATCH_SIZE(),
from: address(proxy),
to: address(dynamic),
amount: defaults.PER_STREAM_AMOUNT()
Expand Down
3 changes: 2 additions & 1 deletion test/unit/batch-create-with-range/batchCreateWithRange.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ contract BatchCreateWithRange_Unit_Test is Unit_Test {
// Asset flow: proxy owner → proxy → Sablier
// Expect transfers from the proxy owner to the proxy, and then from the proxy to the Sablier contract.
expectCallToTransferFrom({ from: users.sender.addr, to: address(proxy), amount: defaults.TRANSFER_AMOUNT() });
expectMultipleCallsToCreateWithRange({ params: defaults.createWithRange() });
expectMultipleCallsToCreateWithRange({ count: defaults.BATCH_SIZE(), params: defaults.createWithRange() });
expectMultipleCallsToTransferFrom({
count: defaults.BATCH_SIZE(),
from: address(proxy),
to: address(linear),
amount: defaults.PER_STREAM_AMOUNT()
Expand Down
6 changes: 5 additions & 1 deletion test/unit/cancel-multiple/cancelMultiple.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ contract CancelMultiple_Unit_Test is Unit_Test {
vm.warp(defaults.WARP_26_PERCENT());

// Asset flow: proxy owner → proxy → sender
expectMultipleCallsToTransfer({ to: address(proxy), amount: defaults.REFUND_AMOUNT() });
expectMultipleCallsToTransfer({
count: defaults.BATCH_SIZE(),
to: address(proxy),
amount: defaults.REFUND_AMOUNT()
});
expectCallToTransfer({ to: users.sender.addr, amount: defaults.REFUND_AMOUNT() * defaults.BATCH_SIZE() });

bytes memory data = abi.encodeCall(target.cancelMultiple, (lockup, defaults.assets(), streamIds));
Expand Down
2 changes: 1 addition & 1 deletion test/utils/Defaults.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ contract Defaults {
GENERIC CONSTANTS
//////////////////////////////////////////////////////////////////////////*/

uint256 public constant BATCH_SIZE = 10;
uint64 public constant BATCH_SIZE = 10;
Broker public BROKER;
UD60x18 public constant BROKER_FEE = UD60x18.wrap(0);
uint40 public constant CLIFF_DURATION = 2500 seconds;
Expand Down