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

fix: isCancelable in getStream #498

Merged
merged 6 commits into from
May 21, 2023
Merged

Conversation

PaulRBerg
Copy link
Member

@PaulRBerg PaulRBerg commented May 17, 2023

Addresses #497.

Note: this should have been done in #467.

@PaulRBerg PaulRBerg requested a review from andreivladbrg May 17, 2023 18:39
@PaulRBerg PaulRBerg force-pushed the fix/get-stream-is-cancelable branch 2 times, most recently from 0d78723 to 4ccfea8 Compare May 18, 2023 10:13
PaulRBerg added 2 commits May 18, 2023 13:36
test: rename "streamId" to "defaultStreamId"
test: update "getStream" tests
@PaulRBerg PaulRBerg force-pushed the fix/get-stream-is-cancelable branch from 4ccfea8 to 0034359 Compare May 18, 2023 10:36
@PaulRBerg PaulRBerg changed the base branch from main to test/fix-invariant-warp May 18, 2023 10:37
@PaulRBerg PaulRBerg force-pushed the fix/get-stream-is-cancelable branch from 0034359 to c0df5e7 Compare May 18, 2023 10:41
Copy link
Member

@andreivladbrg andreivladbrg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this solution is not ideal because it kinda "lies" about the state of the contract(and minor thing would be the gas implications), but it works. In my opinion renaming the isCancelable storage variable to something like cancebilityBeforeSettledwould have been better.

If you added the internal _statusOf function, we can make it virtual to add it SablierV2Lockup contract and use it in the renounce function(notNull must be added).

https://github.com/sablierhq/v2-core/blob/c0df5e7e17e93b912a30aa8455cc295fab0718c4/src/abstracts/SablierV2Lockup.sol#L160

notNull modifier implicitly called in isCold function:

https://github.com/sablierhq/v2-core/blob/c0df5e7e17e93b912a30aa8455cc295fab0718c4/src/SablierV2LockupLinear.sol#L169-L170

https://github.com/sablierhq/v2-core/blob/c0df5e7e17e93b912a30aa8455cc295fab0718c4/src/SablierV2LockupDynamic.sol#L186-L187

@@ -98,7 +98,7 @@ interface ISablierV2Lockup is
function getWithdrawnAmount(uint256 streamId) external view returns (uint128 withdrawnAmount);

/// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this
/// flag is always `false` regardless of the value of the struct field `isCancelable`.
/// flag is always `false`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's say something like: returns it as it would be false.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. See my comment below. It doesn't matter what is in contract storage; only what end users see.

It's not "as if it would be false" - from the perspective of end users, it is false.

test/fork/lockup-dynamic/Dynamic.t.sol Show resolved Hide resolved
test/invariant/lockup-dynamic/Dynamic.t.sol Show resolved Hide resolved
test/invariant/lockup-linear/Linear.t.sol Show resolved Hide resolved
@@ -2,4 +2,7 @@ getStream.t.sol
├── when the id references a null stream
│ └── it should revert
└── when the id does not reference a null stream
└── it should return the stream
├── when the stream is settled
│ └── it should adjust and return the stream
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's say "adjust the is cancelable flag"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine, but let's say isCancelable (with backticks) to make it clear what we're referring to.

test/unit/lockup-dynamic/get-stream/getStream.tree Outdated Show resolved Hide resolved
Copy link
Member

@andreivladbrg andreivladbrg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this solution is not ideal because it kinda "lies" about the state of the contract(and minor thing would be the gas implications), but it works. In my opinion renaming the isCancelable storage variable to something like cancebilityBeforeSettledwould have been better.

If you added the internal _statusOf function, we can make it virtual to add it SablierV2Lockup contract and use it in the renounce function(notNull must be added).

https://github.com/sablierhq/v2-core/blob/c0df5e7e17e93b912a30aa8455cc295fab0718c4/src/abstracts/SablierV2Lockup.sol#L160

notNull modifier implicitly called in isCold function:

https://github.com/sablierhq/v2-core/blob/c0df5e7e17e93b912a30aa8455cc295fab0718c4/src/SablierV2LockupLinear.sol#L169-L170

https://github.com/sablierhq/v2-core/blob/c0df5e7e17e93b912a30aa8455cc295fab0718c4/src/SablierV2LockupDynamic.sol#L186-L187

@PaulRBerg
Copy link
Member Author

PaulRBerg commented May 19, 2023

this solution is not ideal because it kinda "lies" about the state of the contract

We are not lying about anything - could you please look at this problem from the end users' perspective?

The state of the contract != storage (in a strict sense). The state of the contract is what is made available in the public API.

As I have said in private, it doesn't matter what happens internally in a piece of software as long as the software works as expected for end users.

If you added the internal _statusOf function, we can make it virtual to add it SablierV2Lockup contract and use it in the renounce function

Good idea.

notNull modifier implicitly called in isCold function:

Good catch

PaulRBerg added 2 commits May 19, 2023 20:57
fix: mark "_statusOf" as "internal"
perf: mark "statusOf" as "external"
test: improve writing in "getStream" state trees
@andreivladbrg
Copy link
Member

could you please look at this problem from the end users' perspective?

I am, but I suppose it is harder for me, as an engineer who understands what's underneath.

doesn't matter what happens internally in a piece of software as long as the software works as expected for end users

IMO smart contracts are a special type of software, so this is why I consciously prefer to be paranoid about things.

At the moment I can't provide a malicious scenario that could arise from this, so we can leave it as it is.

@PaulRBerg
Copy link
Member Author

Smart contracts are special, but this is not a prerogative for not solving problems when they arise (my PR solves a problem, although it might do so in a clumsy way, as you suggest).

Anyway. If we can leave it as is, can you approve the PR?

Copy link
Member

@andreivladbrg andreivladbrg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not related to this PR, but I noticed this while reviewing it.

Let's make it external:

https://github.com/sablierhq/v2-core/blob/6b8b4133aea149a76a6d5548f45559948f07aa8b/src/abstracts/SablierV2Lockup.sol#L89-L90

Base automatically changed from test/fix-invariant-warp to main May 21, 2023 14:27
@PaulRBerg PaulRBerg merged commit be2e4d4 into main May 21, 2023
@PaulRBerg PaulRBerg deleted the fix/get-stream-is-cancelable branch May 21, 2023 14:35
@PaulRBerg
Copy link
Member Author

It is not related to this PR, but I noticed this while reviewing it.

Let's make it external:

Not sure which version of the contract you have reviewed, but that commit (6b8b413) is a month old. In the latest version of the SablierV2Lockup abstract (commit be2e4d4), the withdrawableAmountOf function is external:

https://github.com/sablierhq/v2-core/blob/be2e4d409e9c2f755cf34227edc5a76089461b78/src/abstracts/SablierV2Lockup.sol#L89-L97

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants