You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
doc: usage docs for the tokenomics smart contracts (#3082)
## Summary
Document what tokenomics smart contracts functions should be called to
accomplish basic tasks related to the happy path flows: delegation and
staking process.
## Changes
add new smart contracts md file, as well as linked to it
## Limitations and future improvements
## Checklist before requesting a review
- [ ] Is this a breaking change? If it is, be clear in summary.
- [X] Read through code myself one more time.
- [ ] Make sure any and all `TODO` comments left behind are meant to be
left in.
- [ ] Has reasonable passing test coverage?
- [ ] Updated changelog if applicable.
- [X] Updated documentation if applicable.
---------
Co-authored-by: Teo Gebhard <teo@streamr.com>
Copy file name to clipboardExpand all lines: docs/docs/streamr-network/incentives/network-incentives.md
+2Lines changed: 2 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -54,6 +54,8 @@ After this, the operator will continue to operate the nodes and earn. When they
54
54
55
55
## Technical description
56
56
57
+
NOTE: Everything here is "good to know", but this isn't a developer guide. This is a description of the internal mechanics and token flows inside the contracts, on a relatively high level. Please refer to [the smart contracts document](../smart-contracts.md) for how to interact with the contracts.
58
+
57
59
The tokenomics are mainly governed by the following two smart contracts: the Operator contract and the Sponsorship contract. The Operator contract represents an [operator running a Streamr node in the Streamr network](../network-roles/operators.md). The Sponsorship contract holds [the sponsors'](../network-roles/sponsors.md) DATA tokens that `sponsor` a stream, and allocates them as earnings to the staked Operators.
58
60
59
61
Operator contracts are controlled by their operators. The DATA tokens held by the Operator contract are the funds that the controlling operator can `stake` into whichever Sponsorship contracts they like. By staking into a Sponsorship, the operator commits to servicing the sponsored stream.
Please refer to the [network incentives document](./incentives/network-incentives.md) for the high-level description of the tokenomics system. There you also find described two processes: **delegation** and **staking**. In delegation, node operators receive DATA tokens from delegators who then receive a share of the profits generated by the operators. In staking, node operators stake the DATA tokens into Sponsorship contracts, and withdraw earnings; sponsoring is included in the staking process as well.
14
+
15
+
The relevant transactions in the delegation process are:
16
+
- Delegation, sending DATA tokens into the Operator contract: `DATA.transferAndCall(operatorAddress, amountWei, "0x")`
17
+
- Undelegation, requesting DATA tokens back, either partially or in full: `Operator.undelegate(amountWei)`
18
+
- the DATA tokens will only return immediate insofar as the Operator contract happens to hold non-staked tokens. The undelegation goes into a queue that gets resolved when DATA returns to the Operator, either via withdrawing or unstaking. The queue takes always precedence: delegators are paid their DATA before they can be re-staked.
19
+
- in case the operator doesn't withdraw earnings and/or unstake enough tokens to pay out the queued delegators, then after 30 days, anyone can force the Operator contract to unstake from a sponsorship contract: `Operator.forceUnstake(sponsorshipAddress, 0)`
20
+
21
+
The relevant Operator transactions in the staking process are:
22
+
-**Staking**, sending DATA tokens from Operator to Sponsorships: `Operator.stake(sponsorshipAddress, amountWei)`
23
+
- this same function can be used for adding stake, so calling this 2nd time with same arguments will double the stake (*not* idempotent)
24
+
- once staked, the operator must start relaying the streams associated with the Sponsorship, or risk having their stake slashed
25
+
-**Withdrawing**, pulling DATA token earnings from Sponsorship: `Operator.withdrawEarningsFromSponsorships(sponsorshipAddressList)`
26
+
-**Reducing stake**, pulling some stake back from Sponsorship: `Operator.reduceStakeTo(sponsorshipAddress, targetStakeWei)`
27
+
- calling this 2nd time with same arguments will fail with `Sponsorship.CannotIncreaseStakeUsingReduceStakeTo` error
28
+
-**Unstaking**, pulling DATA token earnings and all stake from Sponsorship: `Operator.unstake(sponsorshipAddress, amountWei)`
29
+
- once unstaked, the operator may stop relaying the streams associated with the Sponsorship; they receive their stake back, so flagging and slashing can't happen anymore and thus the obligation to relay has ended
30
+
31
+
The tokens enter the staking process in a transaction from the sponsor(s):
32
+
-**Sponsoring**, sending DATA tokens into the Sponsorship contract: `DATA.transferAndCall(operatorAddress, amountWei, "0x")`
33
+
34
+
### Features for compatibility with arbitrary ERC20 token (no `transferAndCall`)
35
+
36
+
This section doesn't apply to the deployed Streamr contracts that use DATA token (that supports `transferAndCall`). We **discourage** the use these functions with Streamr contracts: `Sponsorship.sponsor`, `Operator.delegate`; use `DATA.transferAndCall` instead as detailed above.
37
+
38
+
The tokenomics contracts have been written in such a way that `transferAndCall` isn't strictly required from the token, but any ERC20 token will also work. This however will require an extra `approve` transaction on the token before the actual smart contract call that does the sponsoring or delegating.
39
+
40
+
When sponsoring, the `transferAndCall` can be replaced with an `IERC20.approve(operatorAddress, amountWei)` followed by `Sponsorship.sponsor`.
41
+
42
+
When delegating, the `transferAndCall` can be replaced with an `IERC20.approve(operatorAddress, amountWei)` followed by `Operator.delegate(amountWei)`.
0 commit comments