-
Notifications
You must be signed in to change notification settings - Fork 3
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
DecentSablier module #100
DecentSablier module #100
Changes from 12 commits
ed62fee
ff7adfa
e0df21e
fa03691
0f747ac
67601b1
da60def
01bdfd1
868d785
a9b8ba9
fac2378
2f5bd7a
1524e94
14b4c7f
a1e23c4
1ec9650
c39571a
a4c4141
84e6c4d
1dfb558
c38c0b6
cf64015
7348526
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity =0.8.19; | ||
|
||
import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; | ||
import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; | ||
import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; | ||
import {LockupLinear} from "./interfaces/sablier/LockupLinear.sol"; | ||
|
||
contract DecentSablierStreamManagement { | ||
string public constant NAME = "DecentSablierStreamManagement"; | ||
|
||
function withdrawMaxFromStream( | ||
ISablierV2LockupLinear sablier, | ||
address recipientHatAccount, | ||
uint256 streamId, | ||
address to | ||
) public { | ||
// Check if there are funds to withdraw | ||
uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId); | ||
if (withdrawableAmount == 0) { | ||
return; | ||
} | ||
|
||
// Proxy the Sablier withdrawMax call through IAvatar (Safe) | ||
IAvatar(msg.sender).execTransactionFromModule( | ||
recipientHatAccount, | ||
0, | ||
abi.encodeWithSignature( | ||
"execute(address,uint256,bytes,uint8)", | ||
address(sablier), | ||
0, | ||
abi.encodeWithSignature( | ||
"withdrawMax(uint256,address)", | ||
streamId, | ||
to | ||
), | ||
0 | ||
), | ||
Enum.Operation.Call | ||
); | ||
} | ||
|
||
function cancelStream( | ||
ISablierV2LockupLinear sablier, | ||
uint256 streamId | ||
) public { | ||
// Check if the stream can be cancelled | ||
LockupLinear.Status streamStatus = sablier.statusOf(streamId); | ||
if ( | ||
streamStatus != LockupLinear.Status.PENDING && | ||
streamStatus != LockupLinear.Status.STREAMING | ||
) { | ||
return; | ||
} | ||
|
||
IAvatar(msg.sender).execTransactionFromModule( | ||
address(sablier), | ||
0, | ||
abi.encodeWithSignature("cancel(uint256)", streamId), | ||
Enum.Operation.Call | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
import {LockupLinear} from "../sablier/LockupLinear.sol"; | ||
|
||
interface ISablierV2Lockup { | ||
function withdrawableAmountOf( | ||
uint256 streamId | ||
) external view returns (uint128 withdrawableAmount); | ||
|
||
function isCancelable(uint256 streamId) external view returns (bool result); | ||
|
||
function withdrawMax( | ||
uint256 streamId, | ||
address to | ||
) external returns (uint128 withdrawnAmount); | ||
|
||
function getStream( | ||
uint256 streamId | ||
) external view returns (LockupLinear.Stream memory); | ||
|
||
function cancel(uint256 streamId) external; | ||
|
||
function statusOf( | ||
uint256 streamId | ||
) external view returns (LockupLinear.Status status); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,4 +25,31 @@ library LockupLinear { | |
address account; | ||
uint256 fee; | ||
} | ||
|
||
struct Stream { | ||
address sender; | ||
uint40 startTime; | ||
uint40 endTime; | ||
uint40 cliffTime; | ||
bool cancelable; | ||
bool wasCanceled; | ||
address asset; | ||
bool transferable; | ||
uint128 totalAmount; | ||
address recipient; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's make sure that this struct (and any others that we've re-created into our various Sablier Interface files) are fully separated from our production contracts. Like, we have our actual contracts, and a handful of Mock contracts to assist with testing. In order to minimize our contract bytecode for the contracts we're deploying to mainnets, let's keep those different structs fully separate and import the necessary files into the necessary contracts. |
||
|
||
/// @notice Enum representing the different statuses of a stream. | ||
/// @custom:value0 PENDING Stream created but not started; assets are in a pending state. | ||
/// @custom:value1 STREAMING Active stream where assets are currently being streamed. | ||
/// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them. | ||
/// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal. | ||
/// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded. | ||
enum Status { | ||
PENDING, | ||
STREAMING, | ||
SETTLED, | ||
CANCELED, | ||
DEPLETED | ||
} | ||
} |
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.
@DarksightKellar
So actually, since
DecentHats_0_1_0
uses this interface, and we want to effectively "lock down" that contract from any changes in the future, we're not able to make any changes to this interface: it'll result in any newly compiled versions ofDecentHats_0_1_0
having different bytecode from that which has already been deployed onchain, which will mean our deployment scripts will attempt to re-deploy it and then publish a new contract address in our NPM package. Which will break our front endsmartAccount
address prediction code.This is definitely frustrating but I'm not sure of any way around it. If you want to make edits to this
ISablierV2LockupLinerar.sol
file, you need to copy the existing code into a new interface file then make the changes there.You can see what I mean by attempting to run the deployment scripts on Sepolia (with this PR as-is). You'll see that it deploys a new instance of
DecentHats_0_1_0
. We need to avoid that.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.
Yeahh I see what you mean. Alrighty I'll make the necessary changes
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.
My recommendation is to create a new interface called
ISablierV2LockupLinearFull.sol
, and just copy in the whole-ass Interface structure from their official repo, to make sure we've got it properly future proofed.I wasn't really thinking about this when creating the first
ISablierV2LockupLinear.sol
file forDecentHats_0_1_0
, and so now we've gotta do this. Oops!edit: might need to the same thing with
LockupLinear.sol
, because there's a reference to that one inDecentHats_0_1_0
, too.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.
@adamgall
XYZ_Full.sol
with future-proof code sounds like the best plan (and name lol). Will updateThere 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.
@adamgall Yeah this is gonna take a little more thought than a quick copy-paste. Not more difficult, just mismatching variables names and a potential package install (@prb/math/src/UD60x18.sol), or cherry picking which code to copy-paste instead of all.
I'll push what I have meantime, which uses
XYZ.sol
andXYZ_2.sol
for locked original, and edited code respectivelyThere 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.
@DarksightKellar i've taken the liberty of finishing this cleanup effort. i think it's all good now
See these commits: