Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion docs/concepts/flow/01-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Total debt is the amount of tokens owed to the recipient. This value is further
### Snapshot debt and Snapshot time

A snapshot is an event during which snapshot debt and snapshot time of a Flow stream are updated. **Snapshot debt** is
the debt accumulated since the previous snapshot. The UNIX timestamp at which snapshot debt is updated is called
the debt accumulated until the previous snapshot. The UNIX timestamp at which snapshot debt is updated is called
**Snapshot time**.

At snapshot, the following operations are taking place:
Expand All @@ -67,6 +67,14 @@ rps \cdot (\text{block.timestamp} - \text{snapshot time})}_\text{ongoing debt}
\text{snapshot time} = \text{block.timestamp}
```

### Ongoing debt

Ongoing debt is the debt accumulated since the previous snapshot. It is calculated as the following:

```math
\text{ongoing debt} = rps \cdot (\text{block.timestamp} - \text{snapshot time})
```

Therefore, at any point in time, total debt can also be defined as:

```math
Expand Down
80 changes: 65 additions & 15 deletions docs/concepts/flow/02-statuses.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,83 @@ A stream can have the following characteristics:
| Solvent | `STREAMING_SOLVENT`, `PAUSED_SOLVENT`, `VOIDED` | Total debt <ins>not exceeding</ins> the stream balance. |
| Insolvent | `STREAMING_INSOLVENT`, `PAUSED_INSOLVENT` | Total debt <ins>exceeding</ins> the stream balance. |

## Diagram
## State transitions

The following diagram illustrates the statuses and the allowed transitions between them:

```mermaid
flowchart LR
N[NULL]
V[VOIDED]
N(NULL)
V(VOIDED)

subgraph Paused
subgraph PAUSED
direction RL
PS[PAUSED_SOLVENT]
PI[PAUSED_INSOLVENT]
PS(SOLVENT)
PI(INSOLVENT)
PI -- "deposit" --> PS
end

subgraph Streaming
subgraph STREAMING
direction LR
SS[STREAMING_SOLVENT]
SI[STREAMING_INSOLVENT]
SS(SOLVENT)
SI(INSOLVENT)
SI -- "deposit" --> SS
SS -- "time" --> SI
end

Streaming -- pause --> Paused
Streaming -- void --> V
Paused -- restart --> Streaming
Paused -- void --> V
STREAMING -- pause --> PAUSED
STREAMING -- void --> V
PAUSED -- restart --> STREAMING
PAUSED -- void --> V

N -- create (rps > 0) --> Streaming
N -- create (rps = 0) --> Paused
N -- create (rps > 0) --> STREAMING
N -- create (rps = 0) --> PAUSED
```

## Functions Statuses Interaction

### NULL stream

```mermaid
flowchart LR
CR[CREATE] --> NULL((NULL))
```

### STREAMING stream

```mermaid
flowchart TD
STR((STREAMING))

ADJRPS[ADJUST_RPS] --> STR
DP[DEPOSIT] --> STR
RFD[REFUND] --> STR
PS[PAUSE] --> STR
VD[VOID] --> STR
WTD[WITHDRAW] --> STR
```

### PAUSED stream

```mermaid
flowchart TD
PSED((PAUSED))

DP([DEPOSIT]) --> PSED
RFD([REFUND]) --> PSED
RST([RESTART]) --> PSED
VD([VOID]) --> PSED
WTD([WITHDRAW]) --> PSED
```

### VOIDED stream

```mermaid
flowchart LR
VOID((VOIDED))

RFD([REFUND]) --> VOID
WTD([WITHDRAW]) --> VOID
```

## Q&A
Expand All @@ -78,3 +124,7 @@ can pause it.
A: Both sender and recipient can void the stream. This is especially useful when either party wants to stop the stream
immediately. Once a stream is voided, it cannot be restarted. If there is uncovered debt, it will be reset to 0. So to
ensure that your recipient does not lose on any streamed amount, you can deposit into the stream before voiding it.

```

```
2 changes: 1 addition & 1 deletion docs/concepts/lockup/06-statuses.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ A stream status can have one out of two "temperatures":
| Warm | Pending, Streaming | The passage of time alone <ins>can</ins> change the status. |
| Cold | Settled, Canceled, Depleted | The passage of time alone <ins>cannot</ins> change the status. Only a user action can do this. |

## Diagram
## State transitions

The following diagram illustrates the statuses and the allowed transitions between them:

Expand Down
36 changes: 26 additions & 10 deletions docs/concepts/lockup/07-hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,34 @@ If the recipient contract is not on the allowlist, the hooks will not be execute

:::

### Cancel hook

```mermaid
sequenceDiagram
actor Sender

Sender ->> SablierLockup: cancel()
SablierLockup -->> Recipient: onSablierLockupCancel()
Recipient -->> SablierLockup: return selector
SablierLockup -->> Sender: transfer unstreamed tokens
break if hook reverts
Recipient -->> SablierLockup: ❌ tx fail
end
```

### Withdraw hook

```mermaid
flowchart LR
S((Sender))
A((Anyone))
subgraph Core
L[SablierLockup]
sequenceDiagram
actor Anyone

Anyone ->> SablierLockup: withdraw()
SablierLockup -->> Recipient: onSablierLockupWithdraw()
Recipient -->> SablierLockup: return selector
SablierLockup -->> Recipient: transfer streamed tokens
break if hook reverts
Recipient -->> SablierLockup: ❌ tx fail
end
R((Recipient))
S -- "cancel" --> L
L -- "onSablierLockupCancel" --> R
A -- "withdraw" --> L
L -- "onSablierLockupWithdraw" --> R
```

## Next steps
Expand Down
136 changes: 95 additions & 41 deletions docs/reference/flow/01-diagrams.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ sidebar_position: 1
title: "Diagrams"
---

## Abbreviations

| Abbreviation | Full name | Description |
| ------------ | --------------- | ----------------------------------------------------------- |
| bal | Stream balance | Balance of the stream |
| cd | Covered debt | Portion of the total debt covered by the stream balance |
| elt | Elapsed time | Time elapsed in seconds since the last snapshot |
| od | Ongoing debt | Debt accumulated since the last snapshot |
| now | Current time | Same as `block.timestamps` |
| rps | Rate per second | Rate at which tokens are streamed per second |
| sd | Snapshot debt | Debt accumulated until the last snapshot |
| st | Snapshot time | Time of the last snapshot |
| td | Total debt | Sum of sd and od, also same as sum of cd and ud |
| ud | Uncovered debt | Portion of the total debt not covered by the stream balance |

## Flow Storage Layout

Each Flow contract is a singleton that stores all streams created by that contract's users. The following diagrams
Expand All @@ -13,40 +28,93 @@ provide insight into the storage layout. To see the list of all storage variable
```mermaid
flowchart LR
storage[(Storage)]
bal([Balance - bal])
rps([RatePerSecond - rps])
sd([SnapshotDebtScaled - sd])
st([Snapshot Time - st])
bal([bal])
rps([rps])
sd([sd])
st([st])

storage --> bal
storage --> rps
storage --> sd
storage --> st
```

## Token Balance Actions
## Token Flows

The following three functions lead to tokens flow in and out of a stream:

### Deposit

Anyone can deposit into a stream.

```mermaid
flowchart LR
erc_transfers[(ERC20 Transfer Actions)]
dep([Deposit - add])
ref([Refund - remove])
wtd([Withdraw - remove])

erc_transfers --> dep
erc_transfers --> ref
erc_transfers --> wtd
sequenceDiagram
actor Anyone

Anyone ->> Flow: deposit()
Anyone -->> Flow: Transfer tokens
```

$~$
### Refund

Only sender can refund from the stream that he created.

```mermaid
sequenceDiagram
actor Sender

Sender ->> Flow: refund()
Flow -->> Sender: Transfer unstreamed tokens
```

### Withdraw

Anyone can call withdraw on a stream as long as `to` address matches the recipient. If recipient/operator is calling
withdraw on a stream, they can choose to withdraw to any address.

```mermaid
sequenceDiagram
actor Anyone

Anyone ->> Flow: withdraw()
activate Flow
Create actor Recipient
Flow -->> Recipient: Transfer streamed tokens
deactivate Flow

Recipient ->> Flow: withdraw()
activate Flow
Create actor toAddress
Flow -->> toAddress: Transfer streamed tokens
deactivate Flow
```

## Debts

### Covered debt

```mermaid
flowchart TD
di0{ }:::blue0
di1{ }:::blue0
cd([cd])
res_0([0 ])
res_bal([bal])
res_sum([td])


cd --> di0
di0 -- "bal = 0" --> res_0
di0 -- "bal > 0" --> di1
di1 -- "ud > 0" --> res_bal
di1 -- "ud = 0" --> res_sum
```

### Ongoing Debt

```mermaid
flowchart TD
rca([Ongoing Debt - od])
rca([od])
di0{ }
di1{ }
res_00([0 ])
Expand All @@ -62,15 +130,10 @@ di1 -- "now > st" --> res_rca

### Uncovered Debt

**Notes:** A non-zero uncovered debt implies:

1. `bal < sd` when the status is `PAUSED`
2. `bal < sd + od` when the status is `STREAMING`

```mermaid
flowchart TD
di0{ }:::red1
sd([Uncovered Debt - ud])
sd([ud])
res_sd(["td - bal"])
res_zero([0])

Expand All @@ -79,34 +142,25 @@ flowchart TD
di0 -- "bal >= td" --> res_zero
```

### Covered debt
### Total Debt

```mermaid
flowchart TD
di0{ }:::blue0
di1{ }:::blue0
di2{ }:::blue0
cd([Covered Debt - cd])
res_0([0 ])
res_bal([bal])
res_sd([sd])
res_sum([td])

rca([td])
di0{ }
res_00([sd ])
res_01(["sd + od"])

cd --> di0
di0 -- "bal = 0" --> res_0
di0 -- "bal > 0" --> di1
di1 -- "ud > 0" --> res_bal
di1 -- "ud = 0" --> di2
di2 -- "paused" --> res_sd
di2 -- "streaming" --> res_sum
rca --> di0
di0 -- "rps == 0" --> res_00
di0 -- "rps > 0" --> res_01
```

### Refundable Amount
## Refundable Amount

```mermaid
flowchart TD
ra([Refundable Amount - ra])
ra([Refundable Amount])
res_ra([bal - cd])
ra --> res_ra
```
Loading