Replies: 3 comments 1 reply
-
→ SablierV2Adminable → nftDescriptor → withdrawMultiple Note: I was in favor of enabling the sender to call the "multiple", which would have made the name not misleading. → maxFee
Good point, we should explain this in our docs. |
Beta Was this translation helpful? Give feedback.
-
Great feedback, thanks, @razgraf! → transferAdmin
Good catch. We will remove that placeholder variable, and save a little gas by doing so. → nftDescriptor
I agree. As you said on Slack, having the ability to swap out the NFT descriptor contract would be helpful if and when (i) we want to launch without the NFT art and (ii) there is a bug in the SVG generator algorithm. We will implement an admin-callable → withdrawMultiple
(C) doesn't have just an economic benefit. The more important aspect is that it is a permissionless escape-hatch in case the recipient is an entity that can neither interact with Sablier contracts nor approve an ERC-721 operator (e.g., a Binance address).
I don't follow this, i.e., I don't see why the name is misleading. Could you explain what The noun that "multiple" is attached to is "streams", and this is indicated by the name of the first parameter: We've iterated on the name of this function quite a bit; it used to be called
That is fine. As explained above, the main advantage of allowing the sender to withdraw is protection against cases where stream recipients are addresses that cannot interact with Sablier. It's unlikely that all recipients of a batch stream creation are invalid, but even if the unlikely case that this happens, the sender can call
Gas cost is not the primary concern here. Security, maintenance, and fitness-for-purpose are. @andreivladbrg addressed the first two points with his answer; I will tackle the last point. How useful would it be to have this functionality to withdraw to multiple accounts from multiple streams? What monster of a UI form would that be? I would rather invest that frontend effort into building airstreams and V3. Users can withdraw from V2 to one account, and then parcel out their tokens as they wish with MetaMask. There's no need to reinvent the wheel in our own contracts. → maxFee
As hinted at here, there are gas optimization and security reasons for reusing the But concerning the docs, I agree. This is the perfect use case for a diagram where the protocol and the broker fee are visually stacked. → others
Noice.
One would hope so! We have an invariant test that gives us confidence that this is the case:
I suggest you skim through EIP-3156 since all the In the pro contract, you may be particularly interested to read the NatSpec of the Finally, to get a better handle on the pro contract, I also recommend you install the Copilot Labs extension and use its "Explain" feature. It's the perfect tool for this job. |
Beta Was this translation helpful? Give feedback.
-
Closing, as we've settled and/ or responded to all points. |
Beta Was this translation helpful? Give feedback.
-
Some questions and feedback for the current state of the contracts as of #2de2f40.
SablierV2Adminable
→ transferAdmin
Similar to an optimization made in prb-proxy I suggest getting rid of the oldAdmin placeholder. The transfer method can only be accessed by msg.sender which is in this situation the old admin. No need to use that extra contextual variable.
https://github.com/sablierhq/v2-core/blob/d7f46c1212ebf9e56b93dfa1acec910b0193e0e9/src/abstracts/SablierV2Adminable.sol#L34-L42
SablierV2Lockup
→ nftDescriptor
The logic of having a separate contract for the descriptor was (aside from separation of concerns and freezing purposes) to be able to fix visual bugs or update it later. I see that we're storing the descriptor address in an immutable value with no possibility of updating it later on. I suggest we implement a setter for this value.
https://github.com/sablierhq/v2-core/blob/d7f46c1212ebf9e56b93dfa1acec910b0193e0e9/src/abstracts/SablierV2Lockup.sol#L27
→ withdrawMultiple
The permission schema for "who can withdraw" (from an item) is (a) a recipient, (b) an authorized person or (c) the sender, as long as the withdraw is directed to the current recipient. (C) is very smart as it allows the sender to pay for the transaction, thus relieving the recipient from that cost.
The "multiple" version unfortunately limits this ability to just the recipient. Some notes:
I think the name of the function is a bit misleading in the sense that withdrawMultiple != x * withdraw .
We could use structs for this one, if gas costs allow it (as in a struct containing {streamId, to, amount} ) mainly for consistency - a nice side effect: it would unlock the ability to target separate account (separate to)
→ maxFee
I see that we're using the same MAX_FEE value for both broker fees and protocol fees. This again is a good place to either split the two or make sure we explain in the docs that the actual maximum fee you could pay from your principal is 2 * MAX_FEE (broker + protocol).
https://github.com/sablierhq/v2-core/blob/d7f46c1212ebf9e56b93dfa1acec910b0193e0e9/src/libraries/Helpers.sol#L29-L40
SablierV2Config, SablierV2LockupLinear, SablierV2Comptroller and SablierV2NftDescriptor
These look good and I haven't found any issues with them (neither logical nor subjective). Complex actions will most of the times benefit from a check against the initial deposit amount, so "extracting" money from outside of a stream seems impossible at the moment, which is a good thing.
SablierV2LockupPro, FlashLoans
Review on-going.
Beta Was this translation helpful? Give feedback.
All reactions