-
Notifications
You must be signed in to change notification settings - Fork 53
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
Segment[] array, comptroller, protocol and operator fees, structified parameters, via IR, PRBMath types, major tests refactor #220
Conversation
docs: improve wording in NatSpec refactor: define "MAX_SEGMENT_COUNT" in "ISablierV2Pro" feat: add "MAX_GLOBAL_FEE" in "SablierV2" feat: implement "Ownable" in "SablierV2" test: add helper functions "bound" test: add "owner" user test: deploy the contracts from the "owner" user test: improve wording in comments test: rename non-compliant token test: test "setGlobalFee" function
build: enable "--via-ir" in Foundry config and override default steps build: set "main" branch for "prb-math" in ".gitmodules" build: upgrade to latest "forge-std" and "prb-math" chore: improve wording in NatSpec and code comments docs: change "Reads" to "Queries" in constant functions' NatSpec docs: mention "Transfer" event in create functions' NatSpec feat: add "checkAndCalculateFees" helper in "Helpers" library feat: add protocol revenues (WIP) feat: add "SablierV2Comptroller" contract feat: link comptroller in "SablierV2Linear" contract feat: set comptroller in "SablierV2Linear" constructor feat: set comptroller in "SablierV2Pro" constructor refactor: mint NFT after bumping "nextStreamId" refactor: load protocol fees from comptroller refactor: rename "depositAmount" to "grossDepositAmount" in create function refactor: rename global fees to protocol fees refactor: rename "MAX_GLOBAL_FEE" to "MAX_FEE" refactor: rename "Validations" library to "Helpers" test: import typed "bound" utils from PRBMath and delete local test: load comptroller in "UnitTest" test: test "setProtocolFee" function in "SablieV2Comptroller"
chore: improve wording in code comments docs: improve wording in NatSpec docs: be more specific in NatSpec for "MAX_FEE" refactor: rename "createWithDuration" function to "createStream" refactor: rename "depositAmount" arg to "grossDepositAmount" refactor: reverse order of "operator" and "operatorFee" args test: add "DEFAULT_" prefix to all constants test: add "deployAndDealToken" helper test: add "CreateStreamArgs" and "DefaultArgs" structs test: add tests for when protocol and operator fee are too high in "createStream" tests test: assert NFT has been minted in "token missing return value" testing branch in "createStream" tests test: delete now stale testing branches in "createStream" tests test: delete unneeded constants ("STARTING_BLOCK_TIMESTAMP", "CLIFF_DURATION", and others) test: fuzz all args in "createStream" tests (except for "sender" and "cancelable") test: fuzz args in "cliffTime > stopTime" testing branch in "createStream" tests test: fuzz args in "startTime > cliffTime" testing branch in "createStream" tests test: fuzz token decimals in "createStream" tests test: order assertions alphabetically test: rename "DEPOSIT_AMOUNT_DAI" to "GROSS_DEPOSIT_AMOUNT" test: replace "daiStream" and "usdcStream" with "defaultStream" test: simplify and improve tests for "createStream" function (formerly "create") test: use "ERC20" instead of "ERC20GodMode" test: use default args instead of struct instance in create stream helpers
test: expect event to be emitted in "testCreateStream__TokenMissingReturnValue" test: add "DEFAULT_OPERATOR_FEE_AMOUNT" constant
docs: be more specific in NatSpec perf: use "msg.sender" instead of "owner" in "setComptroller"; refactor: add "override" keyword to "setComptroller" test: add "DEFAULT_PROTOCOL_FEE" and "DEFAULT_PROTOCOL_FEE_AMOUNT" test: change prank to "users.owner" in "CallerOwner" modifier test: fix typo in non-cancelable streams tests test: improve wording in code comments test: test "claimProtocolRevenues" function
test: add simple "@dev" NatSpec for all "setUp" functions
test: delete unused imports
docs: add "Notes:" section in NatSpec docs: improve formatting and wording in NatSpec refactor: rename internal function "_create" to "_createWithRange" refactor: rename "createStream" to "createWithDuration" style: run prettier to fix formatting issues
test: add "boundUint40" helper function test: add constants "DEFAULT_CLIFF_DURATION" and "DEFAULT_TOTAL_DURATION" test: add "CreateWithDurationArgs" helper struct test: add explanatory code comments in "createWithDuration" tests test: assert stream id has been bumped in "testCreateWithDuration" test: expect calls to token contract in "testCreateWithDuration" test: use "bound" instead of "vm.assume" in "createWithDuration" tests
chore: improve wording in code comments docs: improve wording in NatSpec ci: fuzz 10,000 times refactor: reverse order of "returnAmount" and "withdrawAmount" in "Cancel" event test: add "createDefaultStreamWithStopTime" helper function test: add more explanatory code comments test: add test for when the recipient does not revert in "cancel" test: add test for when the recipient reentries in "cancel" test: create default stream in "StreamExistent" modifier in "SablierV2Linear" tests test: delete stale constant "TIME_OFFSET" and use "DEFAULT_TIME_WARP" test: delete usdc token and "usdcStream" test: expect calls to token contracts in all "SablierV2Linear" tests test: explain the role of each user in "Users" struct test: improve wording in modifiers, test function names and test trees test: merge leaves in single, bulkier tests test: move "former recipient" tests higher up the tree test: refactor "NonReverting" to "Good" test: refer to recipient as "NFT owner" in NFT existence tests test: rename "createDefaultDaiStream" to "createDefaultStream" test: rename "createNonCancelableDaiStream" to "createDefaultStreamNonCancelable" test: rename "daiStreamId" to "defaultStreamId" test: rename "decimals" to "tokenDecimals" test: rename "defaultStreamId" to just "streamId" test: rename "DEFAULT_TIME_OFFSET" to "DEFAULT_TIME_WARP" test: rename "nonCancelableDefaultStreamId" to just "streamId" test: reorder constants and functions alphabetically test: set default protocol fee in base "setUp" function test: simplify and improve all tests for "SablierV2Linear" tests test: test for NFT existence only when necessary test: update test trees to conform to fuzzing logic test: use "defaultStream" values instead of "users" test: use named args in "wihdraw" and "withdrawAll" calls test: use "ownerOf" instead of "getRecipient" in NFT existence tests
chore: improve wording in code comments docs: improve wording in NatSpec comments fix: calculate fees before checking linear args fix: handle case when "grossDepositAmount" is zero fix: rename "SablierV2__GrossDepositAmountZero" to "SablierV2__NetDepositAmountZero" perf: split "getWithdrawableAmount" in two subfunctions in "SablierV2Pro" refactor: change order of args in "createWithDeltas" and "createWithMilestones" refactor: do not emit "stopTime" in "CreateProStream" event refactor: do not return "streamId" in internal create function in "SablierV2Pro" refactor: record the fee after creating the stream refactor: rename "createWithDuration" to "createWithDeltas" in "SablierV2Pro" refactor: rename "createWithRange" to "createWithMilestones" in "SablierV2Pro" refactor: rename "depositAmount" to "grossDepositAmount" in external create functions refactor: rename "depositAmount" to "netDepositAmount" in internal create functions refactor: rename "DepositAmountNotEqualToSegmentAmountsSum" to "NetDepositAmountNotEqualToSegmentAmountsSum" refactor: rename "SegmentCountOutOfBounds" to "SegmentCountTooHigh" refactor: use named args in "safeTransfer" call test: add more explanatory comments test: add "calculateStreamedAmount" helper function test: add "calculateStreamedAmountForMultipleSegments" helper function test: add "calculateStreamedAmountForOneSegment" helper function test: add "CreateStreamArgs" and "DefaultArgs" structs in "SablierV2Pro" tests test: add "CreateStreamArgs" and "DefaultArgs" structs in "SablierV2Pro" tests test: check "operator" is not "recipient" in "testBurn__CallerApprovedOperator" test: cluster "vm.assume" assumptions" to speed up fuzzing test: create default stream in "StreamExistent" modifier in "SablierV2Pro" tests test: delete dummy NatSpec at the top of every "setUp" function test: delete "deployAndDealToken" helper function test: delete token decimals fuzz (useless tests) test: expect calls to token contracts in all "SablierV2Pro" tests test: explain how fuzzing works in tests' NatSpec test: fuzz "eve" in non-sender tests test: improve wording in testing trees test: fix "DEFAULT_" constants values test: fuzz all "SablierV2Pro" tests test: merge leaves in single, bulkier tests test: rename "daiStreamId" to "defaultStreamId" test: rename "defaultStreamId" to just "streamId" test: rename "nonCancelableDaiStreamId" to "streamId" test: set default protocol fee in base "setUp" function test: set "max_test_rejects" to 100,000 in default profile test: rename "createDefaultDaiStream" to "createDefaultStream" test: rename "token" to "nonToken" in non-contract tests test: test protocol fee record in all create function tests test: test protocol fee is recorded by pre-loading the protocol revenues test: update test trees to conform to fuzzing logic test: use "defaultArgs.createWithRange" instead of "defaultStream" test: use "defaultStream.token" instead of "address(dai)" test: use "uint256" for "timeWarp", where possible test: use "ud" instead of "wrap" and "UD60x18.wrap"
refactor: assign to "stream" return arg instead of returning stream style: run Prettier to fix formatting issues
build: add "solarray" dep chore: use spaces instead of tabs in ".gitmodules" test: delete "createDynamicArray" functions
chore: add more explanatory code comments chore: delete stale script "lint:check" chore: improve wording in code comments chore: remove "verbosity = 4" in "ci" profile ci: add concurrency lock to prevent accidental runs docs: improve wording in NatSpec test: add "calculateFeeAmounts" helper function test: add event emit for "createWithDeltas" test: delete "UnitTest" contract test: label test contracts test: fuzz 1,000 times by default test: fix test tree for "createWithDeltas" test: move all test constants in "BaseTest" test: optimize test vars for IR in create function tests test: rename "SablierV2ComptrollerTest" to "ComptrollerTest"
refactor: move "DataTypes" to new "types" directory
refactor: rename "WithdrawAllArraysNotEqual" to "WithdrawArraysNotEqual"
Regarding params - TIL! Thanks for the link. I agree that we should refactor
Not sure what you meant by this, but you can explain offline. |
feat: add "Durations" struct refactor: rename "createWithDuration" to "createWithDurations" (plural) test: add "DEFAULT_DURATIONS" constant test: add more create function helpers test: call only "createWithDeltas" in "createWithDeltas" tests test: call only "createWithDurations" in "createWithDurations" tests
docs: explain that the broker params are option docs: improve wording in NatSpec comments refactor: bundle "operator" and "operatorFee" in "Broker" struct refactor: rename "OperatorFeeTooHigh" to "BrokerFeeTooHigh" test: add "broker" user test: delete unneeded "vm.assume" assumption in "createWithRange" tests test: move broker params at the end test: pass "err" param to "assertEq" assertions in integration tests test: update tests to match latest contract API
build: add "test-optimized" profile to test contracts compiled with --via-ir chore: add "test" and "test:optimized" scripts in "package.json" chore: delete stale "solhint" script chore: delete "real-time-finance" tag in "package.json" ci: test optimized code in "test" job test: add "eq" and "tryEnvString" helper functions tets: conditionally deploy contracts normally or from precompiled source test: improve wording in NatSpec
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be more efficient I am going to submit this review without getting in detail on tests, but I liked the shared
pattern to get rid of the duplicated tests.
Regarding structs I suggest to keep them in their dedicated file and separate them with headers, memory / storage
To solve the size issue in the pro contract is mandatory to move the _calculateWithdrawableAmountForOneSegment
and the _calculateWithdrawableAmountForMultipleSegments
functions in Helpers lib.
/// users so that they don't have to install openzeppelin-contracts and prb-contracts separately. | ||
|
||
import { IERC20 } from "@prb/contracts/token/erc20/IERC20.sol"; | ||
import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets merge this with Math.sol
and also add the hooks interfaces, and ofc we have to rename the file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I am against merging these types with the hooks interfaces. The goal with the Math.sol
and the Tokens.sol
files is to re-export external types so that users don't have to manually install third-party repos for using Sablier. Whereas the hooks are internal.
At a minimum, I may be open to merging the Math.sol
and the Tokens.sol
files in one file - but I can't think of any good name for this merged file. Types.sol
would be ugly, because of the types/Types.sol
path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create a dir called re-exports
and add all of them there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I don't like how that sounds, not at all. End users shouldn't know that these are re-exported types.
Let's sleep on this idea for a while, we will come back to it later. If you have a strong opinion, feel free to create a discussion for tracking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main point is if a user wants to import all of them they must have 3 separeted paths instead of one:
import { X } from "path/File1.sol";
import { Y } from "path/File2.sol";
import { Z } from "path/File3.sol";
vs
import { X, Y, Y } from "path/File.sol";
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exports.sol
// SPDX-License-Identifier: LGPL-3.0
pragma solidity >=0.8.13;
/*//////////////////////////////////////////////////////////////////////////
MATH
//////////////////////////////////////////////////////////////////////////*/
/// All PRBMath types needed in v2-core. It is provided for convenience to
/// users so that they don't have to install PRBMath separately.
import { SD1x18 } from "@prb/math/SD1x18.sol";
import { SD59x18 } from "@prb/math/SD59x18.sol";
import { UD60x18 } from "@prb/math/UD60x18.sol";
/*//////////////////////////////////////////////////////////////////////////
TOKENS
//////////////////////////////////////////////////////////////////////////*/
/// All token interfaces needed in v2-core. It is provided for convenience to users so that they don't
/// have to install openzeppelin-contracts and prb-contracts separately.
import { IERC20 } from "@prb/contracts/token/erc20/IERC20.sol";
import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
/*//////////////////////////////////////////////////////////////////////////
HOOKS
//////////////////////////////////////////////////////////////////////////*/
import { ISablierV2Recipient } from "../hooks/ISablierV2Recipient.sol";
import { ISablierV2Sender } from "../hooks/ISablierV2Sender.sol";
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding merging Math
and Tokens
- I see your point, and as I said above, I am sympathetic to it.
But I do not agree regarding the hooks - it's fine to leave them separate, because the hooks are not "types" per se. They have nothing to do with the user-defined value types of PRBMath, or the structs. They are interface files, which serve a specific purpose.
FYI, even forge-std
has gone down this path of modularization and selective importing - see the discussion here about the rationale for removing the Components.sol
file, which was re-exporting all of the Forge Std components. The TLDR; is that selectively importing files leads to faster compile times, because when you re-export everything in one file, Solidity compiles all of those files even if the user imports just one file.
Also, I don't like any name that contains the term "exports" - let's sleep on this for a while.
test/unit/sablier-v2/linear/create-with-range/createWithRange.tree
Outdated
Show resolved
Hide resolved
Thanks @andreivladbrg, your feedback is excellent.
Glad you like it.
I don't like this separation:
I'm in favor of this proposal, but let's merge this PR as is and we will later come back to this idea in case we don't manage to reduce the size of the contracts in other ways. Another reason why I like this separation is that it makes it possible to perform the pro calculations from outside of the pro contracts - this might be helpful for integrators, or for our periphery contracts. |
…ment" chore: delete unused imports docs: add missing "@inheritdoc" in "SablierV2Comptroller" docs: delete stale requirements in NatSpec refactor: use "ud" instead of "UD60x18.wrap" test: fix typos in testing tree for "createWithRange"
You really didn't get my point Separation by headers// SPDX-License-Identifier: LGPL-3.0
pragma solidity >=0.8.13;
import { IERC20 } from "@prb/contracts/token/erc20/IERC20.sol";
import { SD1x18 } from "@prb/math/SD1x18.sol";
/*//////////////////////////////////////////////////////////////////////////
MEMORY STRUCTS
//////////////////////////////////////////////////////////////////////////*/
/// @notice Simple struct that encapsulates the net deposit amount, the protocol fee amount, and the operator fee
/// amount.
/// @custom:field netDeposit The deposit amount net of fees, in units of the token's decimals.
/// @custom:field protocolFee The protocol fee amount, in units of the token's decimals.
/// @custom:field operatorFee The operator fee amount, in units of the token's decimals.
struct CreateAmounts {
uint128 netDeposit; // ──┐
uint128 protocolFee; // ─┘
uint128 operatorFee;
}
/// @dev This struct is needed to avoid the "Stack Too Deep" error.
struct CreateWithMilestonesArgs {
CreateAmounts amounts;
Segment[] segments;
address sender; // ──┐
uint40 startTime; // │
bool cancelable; // ─┘
address recipient;
address operator;
IERC20 token;
}
/// @dev This struct is needed to avoid the "Stack Too Deep" error.
struct CreateWithRangeArgs {
CreateAmounts amounts;
Range range;
address sender; // ──┐
bool cancelable; // ─┘
address recipient;
address operator;
IERC20 token;
}
/*//////////////////////////////////////////////////////////////////////////
STORAGE STRUCTS
//////////////////////////////////////////////////////////////////////////*/
/// @notice Simple struct that encapsulates the deposit and the withdrawn amounts.
/// @custom:field deposit The amount of tokens that have been originally deposited in the stream, net of fees and
/// in units of the token's decimals.
/// @custom:field withdrawn The amount of tokens that have been withdrawn from the stream, in units of the token's
/// decimals.
struct Amounts {
uint128 deposit; // ───┐
uint128 withdrawn; // ─┘
}
/// @notice Linear stream struct used in the SablierV2Linear contract.
/// @dev The fields are arranged like this to save gas via tight variable packing.
/// @custom:field amounts Simple struct with the deposit and withdrawn amounts.
/// @custom:field segments The arrays of segments used to compose the custom streaming curve.
/// @custom:field sender The address of the sender of the stream.
/// @custom:field isCancelable A boolean that indicates whether the stream is cancelable or not.
/// @custom:field isEntity A boolean that signals the existence of the instance of the struct.
/// @custom:field token The address of the ERC-20 token used for streaming.
struct LinearStream {
Amounts amounts;
Range range;
address sender; // ───┐
bool isCancelable; // │
bool isEntity; // ────┘
IERC20 token;
}
/// @notice Pro stream struct used in the SablierV2Pro contract.
/// @dev The fields are arranged like this to save gas via tight variable packing.
/// @custom:field amounts Simple struct with the deposit and withdrawn amounts.
/// @custom:field segments The arrays of segments used to compose the custom streaming curve.
/// @custom:field sender The address of the sender of the stream.
/// @custom:field isCancelable A boolean that indicates whether the stream is cancelable or not.
/// @custom:field isEntity A boolean that signals the existence of the instance of the struct.
/// @custom:field token The address of the ERC-20 token used for streaming.
struct ProStream {
Amounts amounts;
Segment[] segments;
address sender; // ───┐
uint40 startTime; // │
bool isCancelable; // │
bool isEntity; // ────┘
IERC20 token;
}
/// @notice Range struct used as a field in the linear stream.
/// @custom:field cliff The Unix timestamp for when the cliff period will end.
/// @custom:field start The Unix timestamp for when the stream will start.
/// @custom:field stop The Unix timestamp for when the stream will stop.
struct Range {
uint40 cliff;
uint40 start;
uint40 stop;
}
/// @notice Segment struct used in the SablierV2Pro contract.
/// @custom:field amount The amounts of tokens to be streamed in this segment, in units of the token's decimals.
/// @custom:field exponent The exponent in this segment, whose base is the elapsed time as a percentage.
/// @custom:field milestone The Unix timestamp for when this segment ends.
struct Segment {
uint128 amount;
SD1x18 exponent;
uint40 milestone;
} |
build: upgrade to latest "prb-test" test: add "Constants" test contract and move constants there test: add "isTestOptimizedProfile" helper function test: call "deploySablierContracts" in integration test test: delete "eq" helper function test: delete "immutable" modifier from "DEFAULT_RANGE" and "DEFAULT_SEGMENTS test: document "SharedTest" with a little bit of NatSpec test: initialize users in "BaseTest" instead of "UnitTest" test: move "tryEnvString" to "BaseTest" test: rename "approveContracts" to "approveSablierContracts" test: rename "deployContracts" to "deploySablierContracts" test: separate the labelling of the Sablier contracts and the test contracts test: use "eqString" from "prb-test" instead of local "eq"
I'm sorry, @andreivladbrg, I might have misunderstood you. But the way you have worded your initial suggestion was a bit unclear - you said "I suggest to keep them in their dedicated file" - this is interpretable but I would say it's more easy to interpret as meaning that you meant to create one file for each struct. If you wanted to say to keep all structs in the same file, it would have been better to use the terms "all" and "current file", to communicate the fact that the way they are structured currently is fine. Anyway. As I said in one of the comments above, I wish to keep the |
I think is very helpful
There is nothing wrong with this (nothing to be confused by), the params are still in memory and not stored in our contracts. For me this separation of classifications is just logical. |
Why is one struct meant to be imported more than another? They can just import one if they don't want all of them. |
It wouldn't be if the only in-memory struct is
It might be logical but it would add a lot of comments and headers for separating just one struct from the rest. Looks odd.
The |
refactor: remove "comptroller" and "token" from "checkAndCalculateFees" params
Ofc, the idea is to add the
To import all file is a problem of a uneducated user/integrator, we will make sure to specify this exactly in our documentation on how to interact with sablier. For a newbie user would be more confusing having a dedicated struct file and also to see a struct in the core contracts. |
You would be surprised by how often Solidity files are imported in the global scope - specific symbols have only become popular in the recent years. This was due, in part, to the fact that Solidity contracts used to be tested in JavaScript/ Python.
So why give homework to ourselves and have to document something when we can just hide it away from the public API in the first place?
Uhm, no? A third-party integrator doesn't even have to look at the implementation details. They can just pick up the interface files and the types - and off they go. The actual user-facing create function don't expect a struct as a parameter - if they did, I would have welcomed your suggestion to move the said structs in the |
test: refactor "args" to "params" test: rename "defaultArgs" to just "params"
Description
Implements #11, #22, #117, #202, #203, #206, #207, #208, #209, #210, #211, #214, #217, #218, #219, #223, #225, #226, #230, #231, #236, #237, and #238.
This is the biggest PR that I have ever created in this repository. Documenting the minutiae of all new features and changes I made would be impractical, so I listed only the most significant stuff below.
New Features
Comptroller
We now have a
SablierV2Comptroller
contract. See #206.Protocol Fees
We now have protocol fees (#207).
Operator Fees
We now have operator fees in all create functions (#208).
I opted for not implementing separate special functions that have operator fees.
PRBMath Types
New file
types/MathTypes
that re-exports PRBMath types (#202).Coverage in CI
See #210 and #217.
Changes
Production
cliffDuration
and thetotalDuration
parameters into aDurations
struct (Add a "Durations" struct and use it in "createWithDuration" #236)stopTime
storage property (Get rid of the "stopTime" storage property in the pro contract #225)DataTypes
to dedicatedtypes
directory, and rename it toStructs
, and also delete the library (import structs as is)hooks
directorycancelable
property toisCancelable
(Rename "cancelable" to "isCancelable" in the "Stream" struct #214)cancelAll
tocancelMultiple
andwithdrawAll
towithdrawMultiple
(Rename "cancelAll" to "cancelMultiple" and "withdrawAll" to "withdrawMultiple" #219)createWithDuration
tocreateWithDurations
(Add a "Durations" struct and use it in "createWithDuration" #236)withdrawAmount
torecipientAmount
, andreturnAmount
tosenderAmount
(Rename "withdrawAmount" to "recipientAmount", and "returnAmount" to "senderAmount" #226)create
tocreateWithRange
inSablierV2Linear
create
tocreateWithMilestones
inSablierV2Pro
createWithDuration
tocreateWithDeltas
inSablierV2Pro
protocolFeeAmount
,operatorFeeAmount
, andnetDepositAmount
inCreateAmounts
structstartTime
,cliffTime
, andstopTime
inRange
structsegmentAmounts
,segmentExponents
, andsegmentMilestones
into a single array ofSegment[]
(Bundle "segmentAmounts", "segmentExponents" and "segmentMilestones" into a single array of structs #223)UD60x18.wrap
instead oftoUD60x18
, andSD59x18.wrap
instead oftoSD59x18
(Use "UD60x18.wrap" instead of "toUD60x18" in "getWithdrawableAmount" #230 and Use "SD59x18.wrap" instead of "toSD59x18" in "getWithdrawableAmount" #231)Tests
CreateStreamArgs
andDefaultArgs
structs to improve the readability of the arguments passed in the create function tests._cancel
and_withdraw
functions of theSablierV2Pro
contract (Cover the "_cancel" and "_withdraw" internal functions of "SablierV2Pro" #117)createWithRange
test.--via-ir
enabled (Follow Seaport's Foundry set-up to enable "--via-ir" but avoid it when running tests #217)BaseTest
. There is noUnitTest
contract anymore.linear
instead ofsablierV2Linear
andpro
instead ofsablierV2Pro
.solarray
library instead of our customcreateDynamicArray
helper functions (Ditch the "createDynamicArray" helpers in favor of the "solarray" library #211). I ended up forkingsolarray
and using my fork in our repo, because the canonical repo was lacking many features that we needed (uint40
, PRBMath types, etc.)