Sub-stakes description in docs

pull/1558/head
vzotova 2020-01-09 20:48:43 +03:00
parent 07285f2e57
commit 9d4de7478b
3 changed files with 292 additions and 21 deletions

View File

@ -26,16 +26,16 @@ The entire stake consists of:
* tokens which the staker can withdraw at any moment
* tokens locked for a specific period
A staker may extend the unlock period for any number of portions of their total stake. This divides the stake into smaller parts, each with a unique unlock date in the future. Stakers may also acquire and lock new tokens. The total stake is represented as the sum of all the different sub-stakes active in a given cycle (new cycle every 24h), which includes locked sub-stakes, and any sub-stakes that have passed their unlock date, and can be freely withdrawn. Each sub-stake has a beginning and duration (lock time). When a staker confirms activity each day, the remaining lock time for relevant sub-stakes is reduced.
.. _`Sub-stakes`: https://docs.nucypher.com/en/latest/architecture/sub_stakes.html
Sub stakes get slashed in the order of their remaining lock time, beginning with the shortest so the first portion of the stake to be slashed is the unlocked portion. After that, if necessary, locked sub-stakes are decreased the shortest sub stake is decreased by the required amount; if the adjustment of that sub-stake is insufficient to fulfil the required punishment sum, then the next shortest sub-stake is decreased, and so on. Sub-stakes that begin in the next period are checked separately.
`Sub-stakes`_ get slashed in the order of their remaining lock time, beginning with the shortest so the first portion of the stake to be slashed is the unlocked portion. After that, if necessary, locked sub-stakes are decreased the shortest sub-stake is decreased by the required amount; if the adjustment of that sub-stake is insufficient to fulfil the required punishment sum, then the next shortest sub-stake is decreased, and so on. Sub-stakes that begin in the next period are checked separately.
**Example:**
A staker has 1000 tokens:
* 1st sub stake = 500 tokens locked for 10 periods
* 2nd sub stake = 200 tokens for 2 periods
* 3rd sub stake = 100 tokens locked starting from the next period and locked for 5 periods. The 3rd sub stake is locked for the next period but has not yet been used as a deposit for "work" - not until the next period begins.
* 1st sub-stake = 500 tokens locked for 10 periods
* 2nd sub-stake = 200 tokens for 2 periods
* 3rd sub-stake = 100 tokens locked starting from the next period and locked for 5 periods. The 3rd sub-stake is locked for the next period but has not yet been used as a deposit for "work" - not until the next period begins.
* 200 tokens in an unlocked state (still staked, but can be freely withdrawn).
.. aafig::
@ -65,21 +65,21 @@ Penalty Scenarios:
Result:
* 1st sub stake = 500 tokens locked for 10 periods
* 2nd sub stake = 200 tokens for 2 periods
* 3rd sub stake = 100 tokens locked starting from the next period
* 1st sub-stake = 500 tokens locked for 10 periods
* 2nd sub-stake = 200 tokens for 2 periods
* 3rd sub-stake = 100 tokens locked starting from the next period
* 100 tokens in an unlocked state
* *Scenario 2*: Staker incurs penalty calculated to be worth **300 tokens**:
The unlocked tokens can only cover 200 tokens. In the current period, 700 tokens are locked and 800 tokens are locked for the next period. Therefore, we should reduce amount of locked tokens for the next period and leave unchanged locked amount in the current period. The 3rd sub stake suits for this purpose but it's not the shortest one. So we take the 2nd sub stake (the shortest), reduce it to 100 tokens and add new sub stake with 100 tokens which active only in the current period.
The unlocked tokens can only cover 200 tokens. In the current period, 700 tokens are locked and 800 tokens are locked for the next period. Therefore, we should reduce amount of locked tokens for the next period and leave unchanged locked amount in the current period. The 3rd sub-stake suits for this purpose but it's not the shortest one. So we take the 2nd sub-stake (the shortest), reduce it to 100 tokens and add new sub-stake with 100 tokens which active only in the current period.
Result:
* 1st sub stake = 500 tokens locked for 10 periods
* 2nd sub stake = 100 tokens for 2 periods
* 3rd sub stake = 100 tokens locked starting from the next period for 5 periods
* 4rd sub stake = 100 tokens for 1 period
* 1st sub-stake = 500 tokens locked for 10 periods
* 2nd sub-stake = 100 tokens for 2 periods
* 3rd sub-stake = 100 tokens locked starting from the next period for 5 periods
* 4rd sub-stake = 100 tokens for 1 period
* Remaining 0 tokens
.. aafig::
@ -101,13 +101,13 @@ Penalty Scenarios:
* *Scenario 3*: Staker incurs penalty calculated to be worth **400 tokens**:
The difference from the previous scenario is that should also decrease locked tokens in the current period. At the first step the 2nd sub stake is reduced to 100 tokens. Next step - adjustment for the next period. The shortest sub stake still the same - the 2nd. And we need to deacrese it from 100 to 0 only for the next period. Will be the same if we change duration of the 2nd sub stake from 2 periods to 1 and the other sub stakes remain unchanged.
The difference from the previous scenario is that should also decrease locked tokens in the current period. At the first step the 2nd sub-stake is reduced to 100 tokens. Next step - adjustment for the next period. The shortest sub-stake still the same - the 2nd. And we need to deacrese it from 100 to 0 only for the next period. Will be the same if we change duration of the 2nd sub-stake from 2 periods to 1 and the other sub-stakes remain unchanged.
Result:
* 1st sub stake = 500 tokens locked for 10 periods
* 2nd sub stake = 100 tokens for 1 period
* 3rd sub stake = 100 tokens locked starting from the next period
* 1st sub-stake = 500 tokens locked for 10 periods
* 2nd sub-stake = 100 tokens for 1 period
* 3rd sub-stake = 100 tokens locked starting from the next period
* Remaining 0 tokens
.. aafig::
@ -127,13 +127,13 @@ Penalty Scenarios:
* *Scenario 4*: Staker incurs penalty calculated to be worth **600 tokens**:
Reducing the unlocked remaining tokens, 3rd sub stakes, and the shortest sub stake (2nd) is not enough, so they are all removed. The next shortest sub stake is the 1st which is reduced from 500 to 400.
Reducing the unlocked remaining tokens, 3rd sub-stakes, and the shortest sub-stake (2nd) is not enough, so they are all removed. The next shortest sub-stake is the 1st which is reduced from 500 to 400.
Result:
* 1st sub stake = 400 tokens locked for 10 periods
* 2nd sub stake = 0 tokens for 2 periods
* 3rd sub stake = 0 tokens locked starting from the next period
* 1st sub-stake = 400 tokens locked for 10 periods
* 2nd sub-stake = 0 tokens for 2 periods
* 3rd sub-stake = 0 tokens locked starting from the next period
* Remaining 0 tokens
.. aafig::

View File

@ -0,0 +1,270 @@
Sub-stakes
==========
A staker may extend the unlock period for any number of portions of their total stake. This divides the stake into smaller parts, each with a unique unlock date in the future. Stakers may also acquire and lock new tokens. The total stake is represented as the sum of all the different sub-stakes active in a given cycle (new cycle every 24h), which includes locked sub-stakes, and any sub-stakes that have passed their unlock date, and can be freely withdrawn. Each sub-stake has a beginning and duration (lock time). When a staker confirms activity each day and winding down is enabled, the remaining lock time for relevant sub-stakes is reduced.
Sub-stake remains active until become unlocked and staker get reward for last period of sub-stake by calling ``mint()`` or ``confirmActivity()`` after the last period is surpassed. Each staker can have no more than 30 active sub-stakes. All sub-stakes changes use slots of inactive sub-stakes in the first place and only after that - empty slots in the array. Therefore, obtaining data on past staker locks is not guaranteed.
Operations that modify the sub-stake array
------------------------------------------
Deposit and locking
^^^^^^^^^^^^^^^^^^^
*Methods* : ``deposit(uint256,uint16)``, ``deposit(address,uint256,uint16)``, ``lock(uint256,uint16)``
To become a staker, tokens owner transfers tokens to ``StakingEscrow`` and lock them using one of the ``deposit()`` methods. In case that staker already has some amount of unlocked tokens on the account in the contract then lock can be created using ``lock()`` method. As a result of executing on of the above methods, a new element will be created in the array of sub-stakes with the next period as starting date and with duration equals input parameter.
**Example:**
A staker deposits 900 tokens:
* 1st sub-stake = 900 tokens starting from the next period and locked for 5 periods
.. aafig::
:proportional:
:textual:
stake
^
|
900| +-------------+
| | 1st | period
+---+-------------+--->
0 1 5
Lock prolongation
^^^^^^^^^^^^^^^^^
*Methods* : ``prolongStake(uint256,uint16)``
In order to increase the staking reward, as well as the possibility of obtaining policies with a longer time, staker can increase the locking duration of the sub-stake using the ``prolongStake()`` method. The number of sub-stakes does not change, but the end period of locking in the specified sub-stake will be changed.
**Example:**
A staker prolongs sub-stake for 2 additional periods up to 7:
- Before:
* 1st sub-stake = 900 tokens for 5 periods
- After:
* 1st sub-stake = 900 tokens for 7 periods
.. aafig::
:proportional:
:textual:
Before
stake
^
|
900+----------+
| 1st | period
+----------+--->
0 5
After
stake
^
|
900+-------------+
| 1st | period
+-------------+--->
0 7
Sub-stake division
^^^^^^^^^^^^^^^^^^
*Methods* : ``divideStake(uint256,uint256,uint16)``
If necessary, staker can extend the locking duration only for the part of tokens in a sub-stake (``divideStake()``). Contract method splits desirable sub-stake into two elements: the old sub-stake with changed locked amount and the new sub-stake. New element has the extended locking duration (by the specified number of periods) and the same start period as the old one has. Locked amount in the new sub-stake equals to requested input parameter.
**Example:**
A staker divides sub-stake and extends locking time for 300 tokens for 2 additional periods:
- Before:
* 1st sub-stake = 900 tokens for 5 periods
- After:
* 1st sub-stake = 600 tokens for 5 periods
* 2nd sub-stake = 300 tokens for 7 periods
.. aafig::
:proportional:
:textual:
Before
stake
^
|
900+----------+
| |
| 1st |
| | period
+----------+--->
0 5
After
stake
^
|
900+----------+
| |
| 1st |
300+----------+--+
| 2nd | period
+-------------+--->
0 5 7
Slashing
^^^^^^^^
*See:* `the slashing protocol`_
.. _`the slashing protocol`: https://docs.nucypher.com/en/latest/architecture/slashing.html
Flags that affect the sub-stake array
-------------------------------------
Re-staking
^^^^^^^^^^
*Used in methods* : ``confirmActivity()``, ``mint()``
When re-staking is turned off, the number of locked tokens in sub-stakes does not change by itself.
In case when re-staking parameter is on then all staking reward is locked as the part of each involved sub-stake (inside ``confirmActivity()`` and/or ``mint()``). Accordingly, each such sub-stake has increased locked amount (by reward) and the number of sub-stakes stays unchanged.
**Example:**
A staker has few sub-stakes and calls ``mint()``:
- Before calling:
* 1st sub-stake = 400 tokens for 10 periods
* 2nd sub-stake = 200 tokens for 2 periods
* 3rd sub-stake = 100 tokens locked starting from the next period and locked for 5 periods
* 100 tokens in an unlocked state
- After calling, re-staking is disabled:
* 1st sub-stake = 400 tokens for 10 periods
* 2nd sub-stake = 200 tokens for 2 periods
* 3rd sub-stake = 100 tokens locked starting from the next period and locked for 5 periods
* 170 tokens in an unlocked state
- After calling, re-staking is enabled:
* 1st sub-stake = 450 tokens for 10 periods
* 2nd sub-stake = 220 tokens for 2 periods
* 3rd sub-stake = 100 tokens locked starting from the next period and locked for 5 periods
* 100 tokens in an unlocked state
.. aafig::
:proportional:
:textual:
Before
stake
^
|
700| +----+
| | 3rd|
600+-----+----+
500| +-------------+
| 2nd | 3rd |
400+----------+-------------+----------+
| |
| 1st | period
+-----------------------------------+--->
0 1 2 5 10
After, restaking is enabled
stake
^
|
770| +----+
| | 3rd|
670+-----+----+
| |
550| 2nd +-------------+
| | 3rd |
450+----------+-------------+----------+
| |
| 1st |
| | period
+-----------------------------------+--->
0 1 2 5 10
Winding down
^^^^^^^^^^^^
*Used in methods* : ``confirmActivity()``
Disabled winding down parameter (by default) guarantees that worker must call ``confirmActivity()`` at least N times after parameter will be turned on to unlock sub-stake, where N is locking duration of sub-stake. Thus unlocking date for each sub-stakes shifts by 1 period each period (duration remains the same). In case when winding down is enabled, each ``confirmActivity()`` (no more than once in a period) leads to decreasing of locking duration of each sub-stake. If worker calls ``confirmActivity()`` each period then unlocking date remains unchanged.
**Example:**
A staker has few sub-stakes, worker calls ``сonfirmActivity()`` each period:
- Current period:
* 1st sub-stake = 400 tokens for 10 periods
* 2nd sub-stake = 100 tokens locked starting from the next period and locked for 5 periods
- Next period, winding down is disabled:
* 1st sub-stake = 400 tokens for 10 periods
* 2nd sub-stake = 100 tokens locked starting from the current period and locked for 5 future periods
- Next period, winding down is enabled:
* 1st sub-stake = 400 tokens for 9 periods
* 2nd sub-stake = 100 tokens locked starting from the current period and locked for 4 future periods
.. aafig::
:proportional:
:textual:
Current period
stake
^
|
500| +---------+
| | 2nd |
400+--+---------+----------+
| |
| 1st |
| | period
+-----------------------+--->
0 1 5 10
Next period, winding down is disabled
stake
^
|
500+------------+
| 2nd |
400+------------+----------+
| |
| 1st |
| | period
+-----------------------+--->
1 6 11
Next period, winding down is enabled
stake
^
|
500+----------+
| 2nd |
400+----------+----------+
| |
| 1st |
| | period
+---------------------+----->
1 5 10

View File

@ -145,6 +145,7 @@ Whitepapers
architecture/character
architecture/contracts
architecture/upgradeable_proxy_contracts
architecture/sub_stakes
architecture/slashing
.. toctree::