Rename "onLockupStreamWithdrawn()" hooks to avoid duplicate calls #804
Replies: 3 comments 2 replies
-
Good catch, @smol-ninja, and thanks for the detailed report. I think this problem was introduced in #781 (when the withdrawal hook was added for the sender). I'm leaning towards option 2 on the basis that it doesn't seem worth it to me to optimize the overall design of the contracts based on an edge case (when sender = recipient). The hook names suggested in option 1 are excessively verbose (and I can't think of any good shorter names). The implementation might be simpler than in your code snippet - we can just use if (msg.sender != recipient && recipient.code.length > 0) {
try ISablierV2Recipient(recipient).onLockupStreamWithdrawn({.. /* snip */ ..}) { } catch { }
} else if (msg.sender != sender && sender.code.length > 0) {
try ISablierV2Sender(sender).onLockupStreamWithdrawn({.. /* snip */ ..}) { } catch { }
} |
Beta Was this translation helpful? Give feedback.
-
@smol-ninja could you create an issue out of this discussion, and then close it? |
Beta Was this translation helpful? Give feedback.
-
Tracking it with #822. |
Beta Was this translation helpful? Give feedback.
-
A note to the reader: The following doesn't affect the deployed version of Sablier contracts.
Context
The recent PR: Make withdraw function callable by any account enables anyone to call
withdraw()
on any stream. Each withdrawal attempts to callonLockupStreamWithdrawn()
on both sender and recipient if they are contracts. As discussed privately on Slack, it raises a concern when the stream has the same sender and recipient. 1Problem
We use the same function name
onLockupStreamWithdrawn()
in bothISablierV2Recipient
andISablierV2Sender
. The user is expected to implementonLockupStreamWithdrawn()
with no information regarding which interface he wants to implement it for. This leads to duplicate calls on this function whenwithdraw()
is triggered by a third party and the sender and recipient are the same contract addresses.SablierV2Lockup.sol#L278C1-L297C10
Solutions
Option 1
Rename
onLockupStreamWithdrawn()
callSenderOnLockupStreamWithdrawn()
inISablierV2Sender
callRecipientOnLockupStreamWithdrawn()
inISablierV2Recipient
Because we have other functions
OnLockupStreamCanceled()
andonLockupStreamRenounced()
in theISablierV2Recipient
, we should also consider renaming them to follow the same naming convention.Option 2
When the sender is the same as the recipient,
withdraw()
calls ononLockupStreamWithdrawn()
only once.Footnotes
A user provides liquidity on AMM through a multisig and then locks the liquidity by setting up a stream of LP tokens to the same multisig. The multisig implements
onLockupStreamWithdrawn()
to withdraw liquidity from the AMM every time awithdraw()
is triggered. ↩Beta Was this translation helpful? Give feedback.
All reactions