-
Notifications
You must be signed in to change notification settings - Fork 2
/
ISablierFlow.sol
462 lines (426 loc) Β· 20.8 KB
/
ISablierFlow.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.22;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { UD21x18 } from "@prb/math/src/UD21x18.sol";
import { Broker, Flow } from "./../types/DataTypes.sol";
import { IBatch } from "./IBatch.sol";
import { ISablierFlowBase } from "./ISablierFlowBase.sol";
/// @title ISablierFlow
/// @notice Creates and manages Flow streams with linear streaming functions.
interface ISablierFlow is
IBatch, // 0 inherited interface
ISablierFlowBase // 5 inherited component
{
/*//////////////////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////////////////*/
/// @notice Emitted when the rate per second is updated by the sender.
/// @param streamId The ID of the stream.
/// @param totalDebt The total debt at the time of the update, denoted in token's decimals.
/// @param oldRatePerSecond The old rate per second, denoted as a fixed-point number where 1e18 is 1 token
/// per second.
/// @param newRatePerSecond The new rate per second, denoted as a fixed-point number where 1e18 is 1 token
/// per second.
event AdjustFlowStream(
uint256 indexed streamId, uint256 totalDebt, UD21x18 oldRatePerSecond, UD21x18 newRatePerSecond
);
/// @notice Emitted when a Flow stream is created.
/// @param streamId The ID of the newly created stream.
/// @param sender The address streaming the tokens, which is able to adjust and pause the stream.
/// @param recipient The address receiving the tokens, as well as the NFT owner.
/// @param ratePerSecond The amount by which the debt is increasing every second, denoted as a fixed-point number
/// where 1e18 is 1 token per second.
/// @param token The contract address of the ERC-20 token to be streamed.
/// @param transferable Boolean indicating whether the stream NFT is transferable or not.
event CreateFlowStream(
uint256 streamId,
address indexed sender,
address indexed recipient,
UD21x18 ratePerSecond,
IERC20 indexed token,
bool transferable
);
/// @notice Emitted when a stream is funded.
/// @param streamId The ID of the stream.
/// @param funder The address that made the deposit.
/// @param amount The amount of tokens deposited into the stream, denoted in token's decimals.
event DepositFlowStream(uint256 indexed streamId, address indexed funder, uint128 amount);
/// @notice Emitted when a stream is paused by the sender.
/// @param streamId The ID of the stream.
/// @param sender The stream's sender address.
/// @param recipient The stream's recipient address.
/// @param totalDebt The amount of tokens owed by the sender to the recipient, denoted in token's decimals.
event PauseFlowStream(
uint256 indexed streamId, address indexed sender, address indexed recipient, uint256 totalDebt
);
/// @notice Emitted when a sender is refunded from a stream.
/// @param streamId The ID of the stream.
/// @param sender The stream's sender address.
/// @param amount The amount of tokens refunded to the sender, denoted in token's decimals.
event RefundFromFlowStream(uint256 indexed streamId, address indexed sender, uint128 amount);
/// @notice Emitted when a stream is restarted by the sender.
/// @param streamId The ID of the stream.
/// @param sender The stream's sender address.
/// @param ratePerSecond The amount by which the debt is increasing every second, denoted as a fixed-point number
/// where 1e18 is 1 token per second.
event RestartFlowStream(uint256 indexed streamId, address indexed sender, UD21x18 ratePerSecond);
/// @notice Emitted when a stream is voided by the sender, recipient or an approved operator.
/// @param streamId The ID of the stream.
/// @param sender The stream's sender address.
/// @param recipient The stream's recipient address.
/// @param caller The address that performed the void, which can be the sender, recipient or an approved operator.
/// @param newTotalDebt The new total debt, denoted in token's decimals.
/// @param writtenOffDebt The amount of debt written off by the caller, denoted in token's decimals.
event VoidFlowStream(
uint256 indexed streamId,
address indexed sender,
address indexed recipient,
address caller,
uint256 newTotalDebt,
uint256 writtenOffDebt
);
/// @notice Emitted when tokens are withdrawn from a stream by a recipient or an approved operator.
/// @param streamId The ID of the stream.
/// @param to The address that received the withdrawn tokens.
/// @param token The contract address of the ERC-20 token that was withdrawn.
/// @param caller The address that performed the withdrawal, which can be the recipient or an approved operator.
/// @param withdrawAmount The amount withdrawn to the recipient after subtracting the protocol fee, denoted in
/// token's decimals.
/// @param protocolFeeAmount The amount of protocol fee deducted from the withdrawn amount, denoted in token's
/// decimals.
event WithdrawFromFlowStream(
uint256 indexed streamId,
address indexed to,
IERC20 indexed token,
address caller,
uint128 withdrawAmount,
uint128 protocolFeeAmount
);
/*//////////////////////////////////////////////////////////////////////////
CONSTANT FUNCTIONS
//////////////////////////////////////////////////////////////////////////*/
/// @notice Returns the amount of debt covered by the stream balance, denoted in token's decimals.
/// @dev Reverts if `streamId` references a null stream.
/// @param streamId The stream ID for the query.
function coveredDebtOf(uint256 streamId) external view returns (uint128 coveredDebt);
/// @notice Returns the time at which the total debt exceeds stream balance. If the total debt is less than
/// or equal to stream balance, it returns 0.
/// @dev Reverts on the following conditions:
/// - If `streamId` references a paused or a null stream.
/// - If stream balance is zero.
/// @param streamId The stream ID for the query.
function depletionTimeOf(uint256 streamId) external view returns (uint256 depletionTime);
/// @notice Returns the amount of debt accrued since the snapshot time until now, denoted as a fixed-point number
/// where 1e18 is 1 token.
/// @dev Reverts if `streamId` references a null stream.
/// @param streamId The stream ID for the query.
function ongoingDebtScaledOf(uint256 streamId) external view returns (uint256 ongoingDebtScaled);
/// @notice Returns the amount that the sender can be refunded from the stream, denoted in token's decimals.
/// @dev Reverts if `streamId` references a null stream.
/// @param streamId The stream ID for the query.
function refundableAmountOf(uint256 streamId) external view returns (uint128 refundableAmount);
/// @notice Returns the stream's status.
/// @dev Reverts if `streamId` references a null stream.
/// @param streamId The stream ID for the query.
function statusOf(uint256 streamId) external view returns (Flow.Status status);
/// @notice Returns the total amount owed by the sender to the recipient, denoted in token's decimals.
/// @dev Reverts if `streamId` references a null stream.
/// @param streamId The stream ID for the query.
function totalDebtOf(uint256 streamId) external view returns (uint256 totalDebt);
/// @notice Returns the amount of debt not covered by the stream balance, denoted in token's decimals.
/// @dev Reverts if `streamId` references a null stream.
/// @param streamId The stream ID for the query.
function uncoveredDebtOf(uint256 streamId) external view returns (uint256 uncoveredDebt);
/// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in token decimals. This
/// is an alias for `coveredDebtOf`.
/// @dev Reverts if `streamId` references a null stream.
/// @param streamId The stream ID for the query.
/// @return withdrawableAmount The amount that the recipient can withdraw.
function withdrawableAmountOf(uint256 streamId) external view returns (uint128 withdrawableAmount);
/*//////////////////////////////////////////////////////////////////////////
NON-CONSTANT FUNCTIONS
//////////////////////////////////////////////////////////////////////////*/
/// @notice Changes the stream's rate per second.
///
/// @dev Emits {AdjustFlowStream} and {MetadataUpdate} events.
///
/// Notes:
/// - It updates snapshot debt and snapshot time.
///
/// Requirements:
/// - Must not be delegate called.
/// - `streamId` must not reference a null or a paused stream.
/// - `msg.sender` must be the stream's sender.
/// - `newRatePerSecond` must not equal to the current rate per second.
///
/// @param streamId The ID of the stream to adjust.
/// @param newRatePerSecond The new rate per second, denoted as a fixed-point number where 1e18 is 1 token
/// per second.
function adjustRatePerSecond(uint256 streamId, UD21x18 newRatePerSecond) external;
/// @notice Creates a new Flow stream by setting the snapshot time to `block.timestamp` and leaving the balance to
/// zero. The stream is wrapped in an ERC-721 NFT.
///
/// @dev Emits {CreateFlowStream} event.
///
/// Requirements:
/// - Must not be delegate called.
/// - `sender` must not be the zero address.
/// - `recipient` must not be the zero address.
/// - The `token`'s decimals must be less than or equal to 18.
///
/// @param sender The address streaming the tokens, which is able to adjust and pause the stream. It doesn't
/// have to be the same as `msg.sender`.
/// @param recipient The address receiving the tokens.
/// @param ratePerSecond The amount by which the debt is increasing every second, denoted as a fixed-point number
/// where 1e18 is 1 token per second.
/// @param token The contract address of the ERC-20 token to be streamed.
/// @param transferable Boolean indicating if the stream NFT is transferable.
///
/// @return streamId The ID of the newly created stream.
function create(
address sender,
address recipient,
UD21x18 ratePerSecond,
IERC20 token,
bool transferable
)
external
returns (uint256 streamId);
/// @notice Creates a new Flow stream by setting the snapshot time to `block.timestamp` and the balance to `amount`.
/// The stream is wrapped in an ERC-721 NFT.
///
/// @dev Emits {Transfer}, {CreateFlowStream}, and {DepositFlowStream} events.
///
/// Notes:
/// - Refer to the notes in {deposit}.
///
/// Requirements:
/// - Refer to the requirements in {create} and {deposit}.
///
/// @param sender The address streaming the tokens. It doesn't have to be the same as `msg.sender`.
/// @param recipient The address receiving the tokens.
/// @param ratePerSecond The amount by which the debt is increasing every second, denoted as a fixed-point number
/// where 1e18 is 1 token per second.
/// @param token The contract address of the ERC-20 token to be streamed.
/// @param transferable Boolean indicating if the stream NFT is transferable.
/// @param amount The deposit amount, denoted in token's decimals.
///
/// @return streamId The ID of the newly created stream.
function createAndDeposit(
address sender,
address recipient,
UD21x18 ratePerSecond,
IERC20 token,
bool transferable,
uint128 amount
)
external
returns (uint256 streamId);
/// @notice Makes a deposit in a stream.
///
/// @dev Emits {Transfer} and {DepositFlowStream} events.
///
/// Requirements:
/// - Must not be delegate called.
/// - `streamId` must not reference a null or a voided stream.
/// - `amount` must be greater than zero.
/// - `sender` and `recipient` must match the stream's sender and recipient addresses.
///
/// @param streamId The ID of the stream to deposit to.
/// @param amount The deposit amount, denoted in token's decimals.
/// @param sender The stream's sender address.
/// @param recipient The stream's recipient address.
function deposit(uint256 streamId, uint128 amount, address sender, address recipient) external;
/// @notice Deposits tokens in a stream and pauses it.
///
/// @dev Emits {Transfer}, {DepositFlowStream} and {PauseFlowStream} events.
///
/// Notes:
/// - Refer to the notes in {deposit} and {pause}.
///
/// Requirements:
/// - Refer to the requirements in {deposit} and {pause}.
///
/// @param streamId The ID of the stream to deposit to, and then pause.
/// @param amount The deposit amount, denoted in token's decimals.
function depositAndPause(uint256 streamId, uint128 amount) external;
/// @notice Deposits tokens in a stream.
///
/// @dev Emits {Transfer} and {DepositFlowStream} events.
///
/// Notes:
/// - Refer to the notes in {deposit}.
///
/// Requirements:
/// - Must not be delegate called.
/// - `streamId` must not reference a null stream.
/// - `totalAmount` must be greater than zero. Otherwise it will revert inside {deposit}.
/// - `broker.account` must not be 0 address.
/// - `broker.fee` must not be greater than `MAX_FEE`. It can be zero.
///
/// @param streamId The ID of the stream to deposit on.
/// @param totalAmount The total amount, including the deposit and any broker fee, denoted in token's decimals.
/// @param sender The stream's sender address.
/// @param recipient The stream's recipient address.
/// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the
/// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point percentage.
function depositViaBroker(
uint256 streamId,
uint128 totalAmount,
address sender,
address recipient,
Broker calldata broker
)
external;
/// @notice Pauses the stream.
///
/// @dev Emits {PauseFlowStream} event.
///
/// Notes:
/// - It updates snapshot debt and snapshot time.
/// - It sets the rate per second to zero.
///
/// Requirements:
/// - Must not be delegate called.
/// - `streamId` must not reference a null or an already paused stream.
/// - `msg.sender` must be the stream's sender.
///
/// @param streamId The ID of the stream to pause.
function pause(uint256 streamId) external;
/// @notice Refunds the provided amount of tokens from the stream to the sender's address.
///
/// @dev Emits {Transfer} and {RefundFromFlowStream} events.
///
/// Requirements:
/// - Must not be delegate called.
/// - `streamId` must not reference a null stream.
/// - `msg.sender` must be the sender.
/// - `amount` must be greater than zero and must not exceed the refundable amount.
///
/// @param streamId The ID of the stream to refund from.
/// @param amount The amount to refund, denoted in token's decimals.
function refund(uint256 streamId, uint128 amount) external;
/// @notice Refunds the provided amount of tokens from the stream to the sender's address.
///
/// @dev Emits {Transfer}, {RefundFromFlowStream} and {PauseFlowStream} events.
///
/// Notes:
/// - Refer to the notes in {pause}.
///
/// Requirements:
/// - Refer to the requirements in {refund} and {pause}.
///
/// @param streamId The ID of the stream to refund from and then pause.
/// @param amount The amount to refund, denoted in token's decimals.
function refundAndPause(uint256 streamId, uint128 amount) external;
/// @notice Refunds the entire refundable amount of tokens from the stream to the sender's address.
///
/// @dev Emits {Transfer} and {RefundFromFlowStream} events.
///
/// Requirements:
/// - Refer to the requirements in {refund}.
///
/// @param streamId The ID of the stream to refund from.
function refundMax(uint256 streamId) external;
/// @notice Restarts the stream with the provided rate per second.
///
/// @dev Emits {RestartFlowStream} event.
///
/// Notes:
/// - It updates snapshot debt and snapshot time.
///
/// Requirements:
/// - Must not be delegate called.
/// - `streamId` must not reference a null, or a voided stream.
/// - `msg.sender` must be the stream's sender.
/// - `ratePerSecond` must be greater than zero.
///
/// @param streamId The ID of the stream to restart.
/// @param ratePerSecond The amount by which the debt is increasing every second, denoted as a fixed-point number
/// where 1e18 is 1 token per second.
function restart(uint256 streamId, UD21x18 ratePerSecond) external;
/// @notice Restarts the stream with the provided rate per second, and makes a deposit.
///
/// @dev Emits {RestartFlowStream}, {Transfer}, and {DepositFlowStream} events.
///
/// Notes:
/// - Refer to the notes in {restart} and {deposit}.
///
/// Requirements:
/// - `amount` must be greater than zero.
/// - Refer to the requirements in {restart}.
///
/// @param streamId The ID of the stream to restart.
/// @param ratePerSecond The amount by which the debt is increasing every second, denoted as a fixed-point number
/// where 1e18 is 1 token per second.
/// @param amount The deposit amount, denoted in token's decimals.
function restartAndDeposit(uint256 streamId, UD21x18 ratePerSecond, uint128 amount) external;
/// @notice Voids a stream.
///
/// @dev Emits {VoidFlowStream} event.
///
/// Notes:
/// - It sets snapshot time to the `block.timestamp`
/// - Voiding an insolvent stream sets the snapshot debt to the stream's balance making the uncovered debt to become
/// zero.
/// - Voiding a solvent stream updates the snapshot debt by adding up ongoing debt.
/// - It sets the rate per second to zero.
/// - A voided stream cannot be restarted.
///
/// Requirements:
/// - Must not be delegate called.
/// - `streamId` must not reference a null or a voided stream.
/// - `msg.sender` must either be the stream's sender, recipient or an approved third party.
///
/// @param streamId The ID of the stream to void.
function void(uint256 streamId) external;
/// @notice Withdraws the provided `amount` minus the protocol fee to the provided `to` address.
///
/// @dev Emits {Transfer} and {WithdrawFromFlowStream} events.
///
/// Notes:
/// - It sets the snapshot time to the `block.timestamp` if `amount` is greater than snapshot debt.
/// - A protocol fee may be charged on the withdrawn amount if the protocol fee is enabled for the streaming token.
///
/// Requirements:
/// - Must not be delegate called.
/// - `streamId` must not reference a null stream.
/// - `to` must not be the zero address.
/// - `to` must be the recipient if `msg.sender` is not the stream's recipient.
/// - `amount` must be greater than zero and must not exceed the withdrawable amount.
///
/// @param streamId The ID of the stream to withdraw from.
/// @param to The address receiving the withdrawn tokens.
/// @param amount The amount to withdraw, denoted in token's decimals.
/// @return withdrawnAmount The amount withdrawn to the recipient, denoted in token's decimals. This is input amount
/// minus the protocol fee.
/// @return protocolFeeAmount The protocol fee amount, denoted in the token's decimals.
function withdraw(
uint256 streamId,
address to,
uint128 amount
)
external
returns (uint128 withdrawnAmount, uint128 protocolFeeAmount);
/// @notice Withdraws the entire withdrawable amount minus the protocol fee to the provided `to` address.
///
/// @dev Emits {Transfer} and {WithdrawFromFlowStream} events.
///
/// Notes:
/// - Refer to the notes in {withdraw}.
///
/// Requirements:
/// - Refer to the requirements in {withdraw}.
///
/// @param streamId The ID of the stream to withdraw from.
/// @param to The address receiving the withdrawn tokens.
///
/// @return withdrawnAmount The amount withdrawn to the recipient, denoted in token's decimals.
/// @return protocolFeeAmount The protocol fee amount, denoted in the token's decimals.
function withdrawMax(
uint256 streamId,
address to
)
external
returns (uint128 withdrawnAmount, uint128 protocolFeeAmount);
}