Skip to content

doc: usage docs for the tokenomics smart contracts #3082

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

Merged
merged 5 commits into from
May 27, 2025
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
2 changes: 2 additions & 0 deletions docs/docs/streamr-network/incentives/network-incentives.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ After this, the operator will continue to operate the nodes and earn. When they

## Technical description

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.
Copy link
Contributor

Choose a reason for hiding this comment

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

This file is about Network tokenomics and is under incentives category in the document. We could move this section to a separate file (e.g. to be a section in that smart-contracts.md) as this is not about tokenomics/incentives.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried moving this whole section to another file, I don't think it reads better. Can you make another PR to show what you mean?

Copy link
Contributor

Choose a reason for hiding this comment

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

Why it would be better here than there? As you describe in the text, this section is "a description of the internal mechanics and token flows inside the contracts, on a relatively high level". So it is not about network incentives, but about smart contracts internals.


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.

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.
Expand Down
37 changes: 35 additions & 2 deletions docs/docs/streamr-network/smart-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,40 @@ sidebar_position: 4
---

# Smart contracts
Streamr can be deployed on any EVM compatible chain. Current deployments are Polygon PoS and the Polygon Amoy testnet.
Streamr can be deployed on any EVM compatible chain. Current deployments are Polygon PoS and the Polygon Amoy testnet.

- The Stream Registry [smart contracts](https://github.com/streamr-dev/network-contracts/tree/master/packages/network-contracts/contracts/StreamRegistry)
- Incentive layer Operator [smart contracts](https://github.com/streamr-dev/network-contracts/tree/master/packages/network-contracts/contracts/OperatorTokenomics)
- Incentive layer Operator [smart contracts](https://github.com/streamr-dev/network-contracts/tree/master/packages/network-contracts/contracts/OperatorTokenomics)

## Smart contract usage

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.

The relevant transactions in the delegation process are:
- Delegation, sending DATA tokens into the Operator contract: `DATA.transferAndCall(operatorAddress, amountWei, "0x")`
- Undelegation, requesting DATA tokens back, either partially or in full: `Operator.undelegate(amountWei)`
- 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.
- 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)`

The relevant Operator transactions in the staking process are:
- **Staking**, sending DATA tokens from Operator to Sponsorships: `Operator.stake(sponsorshipAddress, amountWei)`
- this same function can be used for adding stake, so calling this 2nd time with same arguments will double the stake (*not* idempotent)
- once staked, the operator must start relaying the streams associated with the Sponsorship, or risk having their stake slashed
- **Withdrawing**, pulling DATA token earnings from Sponsorship: `Operator.withdrawEarningsFromSponsorships(sponsorshipAddressList)`
- **Reducing stake**, pulling some stake back from Sponsorship: `Operator.reduceStakeTo(sponsorshipAddress, targetStakeWei)`
- calling this 2nd time with same arguments will fail with `Sponsorship.CannotIncreaseStakeUsingReduceStakeTo` error
- **Unstaking**, pulling DATA token earnings and all stake from Sponsorship: `Operator.unstake(sponsorshipAddress, amountWei)`
- 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

The tokens enter the staking process in a transaction from the sponsor(s):
- **Sponsoring**, sending DATA tokens into the Sponsorship contract: `DATA.transferAndCall(operatorAddress, amountWei, "0x")`

### Features for compatibility with arbitrary ERC20 token (no `transferAndCall`)

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.

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.

When sponsoring, the `transferAndCall` can be replaced with an `IERC20.approve(operatorAddress, amountWei)` followed by `Sponsorship.sponsor`.

When delegating, the `transferAndCall` can be replaced with an `IERC20.approve(operatorAddress, amountWei)` followed by `Operator.delegate(amountWei)`.
Loading