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

feat: shape name in create lockup #1094

Merged
merged 2 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"prepare": "husky",
"prettier:check": "prettier --check \"**/*.{json,md,svg,yml}\"",
"prettier:write": "prettier --write \"**/*.{json,md,svg,yml}\"",
"test": "forge test --nmt \"testFork\"",
"test": "forge test",
"test:lite": "FOUNDRY_PROFILE=lite forge test",
"test:optimized": "bun run build:optimized && FOUNDRY_PROFILE=test-optimized forge test"
}
Expand Down
6 changes: 4 additions & 2 deletions script/Init.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ contract Init is BaseScript {
asset: asset,
cancelable: true,
transferable: true,
broker: Broker(address(0), ud60x18(0))
broker: Broker(address(0), ud60x18(0)),
shape: "cliff"
smol-ninja marked this conversation as resolved.
Show resolved Hide resolved
}),
LockupLinear.UnlockAmounts({ start: 0, cliff: 0 }),
LockupLinear.Durations({ cliff: cliffDurations[i], total: totalDurations[i] })
Expand Down Expand Up @@ -82,7 +83,8 @@ contract Init is BaseScript {
asset: asset,
cancelable: true,
transferable: true,
broker: Broker(address(0), ud60x18(0))
broker: Broker(address(0), ud60x18(0)),
shape: "dynamic"
smol-ninja marked this conversation as resolved.
Show resolved Hide resolved
}),
segments
);
Expand Down
18 changes: 12 additions & 6 deletions src/SablierBatchLockup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ contract SablierBatchLockup is ISablierBatchLockup {
asset: asset,
cancelable: batch[i].cancelable,
transferable: batch[i].transferable,
broker: batch[i].broker
broker: batch[i].broker,
shape: batch[i].shape
}),
batch[i].segmentsWithDuration
);
Expand Down Expand Up @@ -115,7 +116,8 @@ contract SablierBatchLockup is ISablierBatchLockup {
cancelable: batch[i].cancelable,
transferable: batch[i].transferable,
timestamps: Lockup.Timestamps({ start: batch[i].startTime, end: endTime }),
broker: batch[i].broker
broker: batch[i].broker,
shape: batch[i].shape
}),
batch[i].segments
);
Expand Down Expand Up @@ -167,7 +169,8 @@ contract SablierBatchLockup is ISablierBatchLockup {
asset: asset,
cancelable: batch[i].cancelable,
transferable: batch[i].transferable,
broker: batch[i].broker
broker: batch[i].broker,
shape: batch[i].shape
}),
batch[i].unlockAmounts,
batch[i].durations
Expand Down Expand Up @@ -217,7 +220,8 @@ contract SablierBatchLockup is ISablierBatchLockup {
cancelable: batch[i].cancelable,
transferable: batch[i].transferable,
timestamps: batch[i].timestamps,
broker: batch[i].broker
broker: batch[i].broker,
shape: batch[i].shape
}),
batch[i].unlockAmounts,
batch[i].cliffTime
Expand Down Expand Up @@ -270,7 +274,8 @@ contract SablierBatchLockup is ISablierBatchLockup {
asset: asset,
cancelable: batch[i].cancelable,
transferable: batch[i].transferable,
broker: batch[i].broker
broker: batch[i].broker,
shape: batch[i].shape
}),
batch[i].tranchesWithDuration
);
Expand Down Expand Up @@ -326,7 +331,8 @@ contract SablierBatchLockup is ISablierBatchLockup {
cancelable: batch[i].cancelable,
transferable: batch[i].transferable,
timestamps: Lockup.Timestamps({ start: batch[i].startTime, end: endTime }),
broker: batch[i].broker
broker: batch[i].broker,
shape: batch[i].shape
}),
batch[i].tranches
);
Expand Down
17 changes: 13 additions & 4 deletions src/SablierLockup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ contract SablierLockup is ISablierLockup, SablierLockupBase {
cancelable: params.cancelable,
transferable: params.transferable,
timestamps: timestamps,
broker: params.broker
broker: params.broker,
shape: params.shape
}),
segments
);
Expand Down Expand Up @@ -201,7 +202,8 @@ contract SablierLockup is ISablierLockup, SablierLockupBase {
cancelable: params.cancelable,
transferable: params.transferable,
timestamps: timestamps,
broker: params.broker
broker: params.broker,
shape: params.shape
}),
unlockAmounts,
cliffTime
Expand Down Expand Up @@ -236,7 +238,8 @@ contract SablierLockup is ISablierLockup, SablierLockupBase {
cancelable: params.cancelable,
transferable: params.transferable,
timestamps: timestamps,
broker: params.broker
broker: params.broker,
shape: params.shape
}),
tranches
);
Expand Down Expand Up @@ -353,6 +356,11 @@ contract SablierLockup is ISablierLockup, SablierLockupBase {
internal
returns (Lockup.CreateEventCommon memory)
{
// Check: the shape name is not greater than 32 bytes to prevent HTML injection attacks.
if (bytes(params.shape).length > 32) {
revert Errors.SablierLockup_ShapeNameTooLong({ nameLength: bytes(params.shape).length, maxLength: 32 });
smol-ninja marked this conversation as resolved.
Show resolved Hide resolved
}

// Effect: create the stream.
_streams[streamId] = Lockup.Stream({
sender: params.sender,
Expand Down Expand Up @@ -393,7 +401,8 @@ contract SablierLockup is ISablierLockup, SablierLockupBase {
cancelable: params.cancelable,
transferable: params.transferable,
timestamps: params.timestamps,
broker: params.broker.account
broker: params.broker.account,
shape: params.shape
});
}

Expand Down
3 changes: 3 additions & 0 deletions src/libraries/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,7 @@ library Errors {

/// @notice Thrown when a function is called on a stream that does not use the expected Lockup model.
error SablierLockup_NotExpectedModel(Lockup.Model actualLockupModel, Lockup.Model expectedLockupModel);

/// @notice Thrown when the shape name is longer than max length.
error SablierLockup_ShapeNameTooLong(uint256 nameLength, uint256 maxLength);
smol-ninja marked this conversation as resolved.
Show resolved Hide resolved
}
15 changes: 15 additions & 0 deletions src/types/DataTypes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ library BatchLockup {
bool transferable;
LockupDynamic.SegmentWithDuration[] segmentsWithDuration;
Broker broker;
string shape;
}

/// @notice A struct encapsulating all parameters of {SablierLockup.createWithDurationsLL} except for the asset.
Expand All @@ -40,6 +41,7 @@ library BatchLockup {
LockupLinear.Durations durations;
LockupLinear.UnlockAmounts unlockAmounts;
Broker broker;
string shape;
}

/// @notice A struct encapsulating all parameters of {SablierLockup.createWithDurationsLT} except for the asset.
Expand All @@ -51,6 +53,7 @@ library BatchLockup {
bool transferable;
LockupTranched.TrancheWithDuration[] tranchesWithDuration;
Broker broker;
string shape;
}

/// @notice A struct encapsulating all parameters of {SablierLockup.createWithTimestampsLD} except for the asset.
Expand All @@ -63,6 +66,7 @@ library BatchLockup {
uint40 startTime;
LockupDynamic.Segment[] segments;
Broker broker;
string shape;
}

/// @notice A struct encapsulating all parameters of {SablierLockup.createWithTimestampsLL} except for the asset.
Expand All @@ -76,6 +80,7 @@ library BatchLockup {
uint40 cliffTime;
LockupLinear.UnlockAmounts unlockAmounts;
Broker broker;
string shape;
}

/// @notice A struct encapsulating all parameters of {SablierLockup.createWithTimestampsLT} except for the asset.
Expand All @@ -88,6 +93,7 @@ library BatchLockup {
uint40 startTime;
LockupTranched.Tranche[] tranches;
Broker broker;
string shape;
}
}

Expand Down Expand Up @@ -136,6 +142,8 @@ library Lockup {
/// @param transferable Boolean indicating whether the stream NFT is transferable or not.
/// @param timestamps Struct encapsulating (i) the stream's start time and (ii) end time, all as Unix timestamps.
/// @param broker The address of the broker who has helped create the stream, e.g. a front-end website.
/// @param shape The name of the stream shape that it should represent. This could be useful to visualize the stream
/// in the UI.
struct CreateEventCommon {
address funder;
address sender;
Expand All @@ -146,6 +154,7 @@ library Lockup {
bool transferable;
Lockup.Timestamps timestamps;
address broker;
string shape;
}

/// @notice Struct encapsulating the parameters of the `createWithDurations` functions.
Expand All @@ -159,6 +168,8 @@ library Lockup {
/// @param transferable Indicates if the stream NFT is transferable.
/// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the
/// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.
/// @param shape An optional name for the stream shape that it should represent. This could be useful to visualize
smol-ninja marked this conversation as resolved.
Show resolved Hide resolved
/// the stream in the UI.
struct CreateWithDurations {
address sender;
address recipient;
Expand All @@ -167,6 +178,7 @@ library Lockup {
bool cancelable;
bool transferable;
Broker broker;
string shape;
}

/// @notice Struct encapsulating the parameters of the `createWithTimestamps` functions.
Expand All @@ -181,6 +193,8 @@ library Lockup {
/// @param timestamps Struct encapsulating (i) the stream's start time and (ii) end time, both as Unix timestamps.
/// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the
/// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.
/// @param shape An optional name for the stream shape that it should represent. This could be useful to visualize
/// the stream in the UI.
smol-ninja marked this conversation as resolved.
Show resolved Hide resolved
struct CreateWithTimestamps {
address sender;
address recipient;
Expand All @@ -190,6 +204,7 @@ library Lockup {
bool transferable;
Timestamps timestamps;
Broker broker;
string shape;
}

/// @notice Enum representing the different distribution models used to create lockup streams.
Expand Down
6 changes: 4 additions & 2 deletions test/fork/LockupDynamic.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ abstract contract Lockup_Dynamic_Fork_Test is Fork_Test {
cancelable: true,
transferable: true,
timestamps: vars.timestamps,
broker: params.broker.account
broker: params.broker.account,
shape: "Dynamic Shape"
}),
segments: params.segments
});
Expand All @@ -172,7 +173,8 @@ abstract contract Lockup_Dynamic_Fork_Test is Fork_Test {
cancelable: true,
transferable: true,
timestamps: vars.timestamps,
broker: params.broker
broker: params.broker,
shape: "Dynamic Shape"
}),
params.segments
);
Expand Down
6 changes: 4 additions & 2 deletions test/fork/LockupLinear.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ abstract contract Lockup_Linear_Fork_Test is Fork_Test {
cancelable: true,
transferable: true,
timestamps: params.timestamps,
broker: params.broker.account
broker: params.broker.account,
shape: "Linear Shape"
}),
cliffTime: params.cliffTime,
unlockAmounts: params.unlockAmounts
Expand All @@ -194,7 +195,8 @@ abstract contract Lockup_Linear_Fork_Test is Fork_Test {
cancelable: true,
transferable: true,
timestamps: params.timestamps,
broker: params.broker
broker: params.broker,
shape: "Linear Shape"
}),
params.unlockAmounts,
params.cliffTime
Expand Down
6 changes: 4 additions & 2 deletions test/fork/LockupTranched.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ abstract contract Lockup_Tranched_Fork_Test is Fork_Test {
cancelable: true,
transferable: true,
timestamps: vars.timestamps,
broker: params.broker.account
broker: params.broker.account,
shape: "Tranched Shape"
}),
tranches: params.tranches
});
Expand All @@ -172,7 +173,8 @@ abstract contract Lockup_Tranched_Fork_Test is Fork_Test {
cancelable: true,
transferable: true,
timestamps: vars.timestamps,
broker: params.broker
broker: params.broker,
shape: "Tranched Shape"
}),
params.tranches
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,13 @@ abstract contract CreateWithTimestamps_Integration_Concrete_Test is Integration_
expectRevert_DelegateCall(callData);
}

function test_RevertWhen_BrokerFeeExceedsMaxValue() external whenNoDelegateCall {
function test_RevertWhen_ShapeNameExceeds32Bytes() external whenNoDelegateCall {
_defaultParams.createWithTimestamps.shape = "this name is longer than 32 bytes";
vm.expectRevert(abi.encodeWithSelector(Errors.SablierLockup_ShapeNameTooLong.selector, 33, 32));
andreivladbrg marked this conversation as resolved.
Show resolved Hide resolved
createDefaultStream();
}

function test_RevertWhen_BrokerFeeExceedsMaxValue() external whenNoDelegateCall whenShapeNameNotExceed32Bytes {
UD60x18 brokerFee = MAX_BROKER_FEE + ud(1);
_defaultParams.createWithTimestamps.broker.fee = brokerFee;
vm.expectRevert(
Expand All @@ -77,7 +83,12 @@ abstract contract CreateWithTimestamps_Integration_Concrete_Test is Integration_
createDefaultStream();
}

function test_RevertWhen_SenderZeroAddress() external whenNoDelegateCall whenBrokerFeeNotExceedMaxValue {
function test_RevertWhen_SenderZeroAddress()
external
whenNoDelegateCall
whenShapeNameNotExceed32Bytes
whenBrokerFeeNotExceedMaxValue
{
_defaultParams.createWithTimestamps.sender = address(0);
vm.expectRevert(abi.encodeWithSelector(Errors.SablierHelpers_SenderZeroAddress.selector));
createDefaultStream();
Expand All @@ -86,6 +97,7 @@ abstract contract CreateWithTimestamps_Integration_Concrete_Test is Integration_
function test_RevertWhen_RecipientZeroAddress()
external
whenNoDelegateCall
whenShapeNameNotExceed32Bytes
whenBrokerFeeNotExceedMaxValue
whenSenderNotZeroAddress
{
Expand All @@ -97,6 +109,7 @@ abstract contract CreateWithTimestamps_Integration_Concrete_Test is Integration_
function test_RevertWhen_DepositAmountZero()
external
whenNoDelegateCall
whenShapeNameNotExceed32Bytes
whenBrokerFeeNotExceedMaxValue
whenSenderNotZeroAddress
whenRecipientNotZeroAddress
Expand All @@ -109,6 +122,7 @@ abstract contract CreateWithTimestamps_Integration_Concrete_Test is Integration_
function test_RevertWhen_StartTimeZero()
external
whenNoDelegateCall
whenShapeNameNotExceed32Bytes
whenBrokerFeeNotExceedMaxValue
whenSenderNotZeroAddress
whenRecipientNotZeroAddress
Expand All @@ -122,6 +136,7 @@ abstract contract CreateWithTimestamps_Integration_Concrete_Test is Integration_
function test_RevertWhen_AssetNotContract()
external
whenNoDelegateCall
whenShapeNameNotExceed32Bytes
whenBrokerFeeNotExceedMaxValue
whenSenderNotZeroAddress
whenRecipientNotZeroAddress
Expand Down
Loading
Loading