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 period (new period 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:

  • Locked amount of tokens

    The locked amount of tokens is fixed for all applicable periods, i.e., it is not possible for a single sub-stake to have a different amount of tokens locked for different periods. To facilitate such a scenario, sub-stakes would need to be divided, see Sub-stake division.

  • Starting period

    The period that the sub-stake begins its locking duration.

  • Locking duration

    Locking duration is defined to be the required number of times that confirmActivity() needs to be called so that the sub-stake is registered as locked for the subsequent period. For example, if a sub-stake has a locking duration of 5 periods it means that the sub-stake will be locked for periods: 1,2,3,4,5 because confirmActivity() would be called during periods 0,1,2,3,4 each time confirming activity for the subsequent period (1,2,3,4,5) respectively. Unless the starting period is specified, the sub-stake is considered locked for the 0th (current) period by default.

A sub-stake remains active until it becomes unlocked, and a staker gets the reward for the last period by calling mint() or confirmActivity() once the last period is surpassed. Each staker can have no more than 30 active sub-stakes which are stored in an array. All sub-stake changes initially reuse slots of inactive sub-stakes for storage in the array, and if there are none, will instead use empty slots. Therefore, attempting to retrieve data about previous inactive sub-stakes is not guaranteed to be successful since the data could have been overwritten.

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, NU tokens must be transferred to the StakingEscrow contract and locked using one of the deposit() methods. If the staker already has unlocked tokens within the account in the contract, then the stake can be locked using the lock() method. If successful, a new element will be created in the array of sub-stakes with the next period as the starting date, and the duration equal to the input parameter.

Example:

A staker deposits 900 tokens:
  • 1st sub-stake = 900 tokens starting from the next period and a locking duration of 5 periods

../_images/aafig-1a253c4b7d0d3fd6a21994e5f40cac280b4b137d.svg

Lock prolongation

Methods : prolongStake(uint256,uint16)

In order to increase the staking reward, as well as the possibility of obtaining policies with a longer timeframe, stakers can increase the duration of their locked sub-stake using the prolongStake() method. The number of sub-stakes does not change, but the locked duration for the specified sub-stake will be increased.

Example:

A staker prolongs sub-stake for 2 additional periods up to 7:
  • Before:
    • 1st sub-stake = 900 tokens with locking duration of 5 periods

  • After:
    • 1st sub-stake = 900 tokens with locking duration of 7 periods

../_images/aafig-0ae2f5996b2ad39eff5a4610e018abd3b0d37135.svg

Sub-stake division

Methods : divideStake(uint256,uint256,uint16)

If necessary, stakers can extend the locking duration for only a portion of their tokens in a sub-stake by using the divideStake() method. This method splits a sub-stake into two elements: the old sub-stake with the reduced locked amount and the new sub-stake with the specified amount. The new sub-stake has the specified locked amount and an extended lock duration, based on the specified number of periods, with the same start period as the old sub-stake.

Example:

A staker divides sub-stake and extends locking time for 300 tokens for 2 additional periods:
  • Before:
    • 1st sub-stake = 900 tokens with locking duration of 5 periods

  • After:
    • 1st sub-stake = 600 tokens with locking duration of 5 periods

    • 2nd sub-stake = 300 tokens with locking duration of 7 periods

../_images/aafig-f930cec4181517f34cdb123db9a21fcf216d9011.svg

Slashing

See: The Slashing Protocol

Flags that affect the sub-stake array

Re-staking

Used in methods : confirmActivity(), mint()

When re-staking is disabled, the number of locked tokens in sub-stakes does not change by itself. However, when re-staking is enabled (default) then all staking rewards are re-locked as part of each relevant sub-stake (inside confirmActivity() and/or mint()). Consequently, each such sub-stake has an increased locked amount (by the accrued staking reward) and the number of sub-stakes remains unchanged.

Example:

A staker has few sub-stakes and calls mint(). Assume that thus far the 1st and 2nd sub-stakes will produce 50 tokens and 20 tokens respectively in rewards:
  • Before calling:
    • 1st sub-stake = 400 tokens with locking duration of 8 periods

    • 2nd sub-stake = 200 tokens with locking duration of 2 periods

    • 3rd sub-stake = 100 tokens locked starting from the next period and a locking duration of 5 periods

    • 100 tokens in an unlocked state

  • After calling, if re-staking is disabled:
    • 1st sub-stake = 400 tokens with locking duration of 8 periods

    • 2nd sub-stake = 200 tokens with locking duration of 2 periods

    • 3rd sub-stake = 100 tokens locked starting from the next period and a locking duration of 5 periods

    • 170 tokens in an unlocked state

  • After calling, if re-staking is enabled:
    • 1st sub-stake = 450 tokens with locking duration of 8 periods

    • 2nd sub-stake = 220 tokens with locking duration of 2 periods

    • 3rd sub-stake = 100 tokens locked starting from the next period and a locking duration of 5 periods

    • 100 tokens in an unlocked state

../_images/aafig-cee7760cf0d3ccb415fe019bc3a8a25444b71d81.svg

Winding down

Used in methods : confirmActivity()

An enabled “winding down” parameter means that each call to confirmActivity() (no more than once in a period) leads to a reduction of the locking duration for each sub-stake. In other words, the sub-stake will unlock after the worker calls confirm-activity() at least N times (no more than once in a period), where N is the locking duration of sub-stake. When disabled (default), the unlock date for each sub-stakes shifts forward by 1 period after each period. In other words, the duration continues to remain the same until the “winding down” parameter is enabled.

Example:

A staker has few sub-stakes, worker calls сonfirmActivity() each period:
  • Current period:
    • 1st sub-stake = 400 tokens with locking duration of 8 periods

    • 2nd sub-stake = 100 tokens locked starting from the next period and a locking duration of 5 periods

  • Next period, if winding down is disabled:
    • 1st sub-stake = 400 tokens with locking duration of 8 periods

    • 2nd sub-stake = 100 tokens locked starting from the current period and a locking duration of 5 future periods

  • Next period, if winding down is enabled:
    • 1st sub-stake = 400 tokens with locking duration of 7 periods

    • 2nd sub-stake = 100 tokens locked starting from the current period and a locking duration of 4 future periods

../_images/aafig-fe652cf39177521fc85fe66c3d65433e74d7e3ea.svg