Skip to content

Latest commit

 

History

History
131 lines (81 loc) · 18.9 KB

sc-delegation-specs.md

File metadata and controls

131 lines (81 loc) · 18.9 KB

Delegation System Smart Contract Specs

Abstract

Any number of eGold holders can participate in staking indirectly by delegating their eGold to existing nodes operators, usually professional validators (staking-as-a-service providers), that choose to accept delegations. We will call node operators or professional validators (staking-as-a-service providers) as Staking Providers or SPs.

An eGold holder indicates which SP candidates they trust, and puts some eGold at stake to support their delegation. If one or more of the SP’s nodes are elected as eligible nodes in an epoch, they will share with them any economic rewards or punishments (when slashing is enabled at the protocol level - this still in R&D phase, so there is no slashing currently), proportional to their delegated stake. Rewards are distributed to the nodes of an SP according to how many times they were selected as leaders, as consensus members and how many transactions have been processed in that epoch. Statistically, this amount per node, considering a sufficient time frame (2-3 weeks), is pretty constant but depends on the randomness source that selects eligible nodes.

In order for eGold holders to be able to stake their tokens without running nodes (they do not have the expertise of running a node, or they do not have enough tokens to run a node, or simply they just want to delegate and not bother running a node) a non-custodial delegation Smart Contract (SC) is deployed for each staking provider (SP) that accepts delegations (non-custodial SC means that the SP does not have access to the delegators’ private keys or funds). Please refer to Delegation smart contract guarantees and invariants section for more info.

The general requirement for one such SC is to compute the rewards generated by the SP’s nodes towards the community members who delegated their tokens through the SC corresponding to that SP. The rewards computation has to take care of when to give the rewards to the registered delegators, how much service fee is taken out and when and how can somebody ask and get back their delegated tokens.

Staking providers will be using a delegation SC that is automatically deployed by a delegation SC manager that accepts registrations of new staking providers. At registration, staking providers will be able to control and set some predefined properties (their fee, for example). Some properties set up at registration can be changed afterwards.

Having a delegation system smart contract does not eliminate the open finance idea where providers can launch their own custom contracts. On the contrary, it helps and encourages both delegators and validators to participate early, by providing them with a proven and well-tested version of the SC that can be used out-of-the-box, without knowledge of coding. We expect many customized variants of similar (but non-system) SCs to be launched soon by SPs that have knowledge to deploy, write and/or modify a delegation SC and also have the need for other customizations.

Note that the Delegation SC is a system smart contract; as such, its code is stored at the system level, and shared between instances (sharing the code among various instances and the separation of code from data is important and an improvement over Ethereum).

Abbreviations and definitions:

  • SC = Smart Contract
  • SP = Staking Provider
  • DM = Delegation SC Manager
  • DSC = Delegation (system) Smart Contract
  • ASC = Auction Smart Contract
  • SSC = Staking Smart Contract

Alt Text Figure 1

ASC keeps the data per staking provider. The total stake amount, total unstaked, number of nodes, list of nodes. The ASC calls the Staking Smart Contract (SSC) with BLSKey as input for actions. SSC keeps the data for every BLSKey - their status (staked, unstaked, waiting, jailed). It can be called only by the Auction Smart Contract (ASC). Thus the SP has to work with the ASC which will call executeOnDestinationContext for interaction with SSC. More info here. Any communication between DSC and SSC is done through ASC. This generally includes staking/unstaking funds and managing nodes.

Roles and available actions

Delegation SC Manager (DM)

Delegation SC Manager (DM) is a system SC that will permite staking providers to register as staking providers. Moreover, besides keeping track of all registered staking providers, the DM will also deploy a DSC for each SP.

One address from an SP can request creation of one DSC only. In order to create a DSC, the SP must provide enough gas and eGold as an SP registration deposit (baseDeposit = 1250 eGold). So DoS and spam are not possible or at least discouraged. This baseDeposit can be used for staking but can be withdrawn only after all nodes are un-staked.

Registration flow: Staking provider sends a transaction to the Metachain to the DM address with createNewDelegationContract(listOfProperties). SP must send enough gas and at least baseDeposit (SP registration deposit) with this transaction. The DM will create a new address in the Metachain for that SP and will “deploy” the delegation system smart contract to that address, calling the init() - init(serviceFee, maxDelegationCap) function as well which will also set the properties given by the SP (some of these properties are upgradable). The function is called precisely once, from the DM, when the DSC is first created. Parameters serviceFee and maxDelegationCap are the initial contract parameters, which can be changed later by the SP through separate functions. The SP is set as the transaction initiator. In addition, the fund call value of this function must be at least the baseDeposit global value, which is currently 1250 eGold. This value represents the initial SP’s funds. They are required in order to force the SP to have skin in the game and prevent spam. The initial owner funds can be more than baseDeposit, if the owner wants to demonstrate to its delegators commitment to its service. These funds are only withdrawable when there are no staked nodes in the SP. Initial owner funds are immediately staked. The SP will receive in a smart contract the result: a generated smart contract’s address and the SP will become the owner of that address. As the owner of that address, the SP will be able to do several actions detailed below in the SP section.

From this moment on, the new address will work as a DSC with the defined properties. Users will be able to delegate their tokens to that address if they choose that SP.

Staking Provider (SP)

This section assumes that a DSC has been generated and deployed by the DM for a given SP, as detailed in the previous section. Recall that the SP is the owner of that DSC. Below we discuss the functions that the SP, or the system or the DM on behalf of the SP, can call on the DSC.

Update fee ( 0-10000) (changeServiceFee(int newServiceFee)) - sets the new service fee. It is a decimal that represents the fraction of rewards taken as a fee. The fee range is restricted by 2 system-level constants: minServiceFee and maxServiceFee, which themselves may be between 0 and 10000.

At the start of a new epoch block, the system calls a special function in the DSC (updateRewards) with the accumulated rewards for the last epoch. In this function, the DSC stores information that is later used to compute rewards for the epoch for each individual delegator. This includes total rewards, max delegation cap, service fee.

Actual rewards per user are not computed now, but as part of claimReward / getUnclaimedRewards, called by the user.

Thus, we avoid the need to recompute all rewards when contract settings are changed.

Contract owner is free to change service fee at any time. Delegators might receive notifications about fee change through their wallet (as an off-chain functionality) or other means (email for example). Thus, if the owner changes the fee abusively this will be visible to the users and they will be free to change their SP.

Nodes actions:

  • add nodes: (addNodes([](BLSPublicKey, SignedMessage))) - send transactions with BLS (public) keys for nodes; signed message (address of DSC) with the private key of that BLS key (add BLS keys for each and all nodes)

  • set delegation cap: (modifyTotalDelegationCap) - set the maximum number of funds this DSC can allocate. SP will generally choose this number based on the number of nodes they can run. However, as stated before, the amount of nodes actually used by the system for validation will be automatically decided by the system at the beginning of each epoch, based on the number of activated nodes and allocated funds. SP is free to increase the cap for any value. If he wants to decrease the cap, he can only do so up to the staked funds value (this helps us avoid forced funds unstaking complexity). If the SP, for whatever reason, wants to run fewer nodes or to shut down the DSC entirely, it can only unregister the nodes. It has no control over user funds. The SP is expected to announce to its delegators that it intends to shutdown the service, and that whatever funds are staked will no longer generate rewards. Afterwards, it is up to the delegators to initiate funds withdrawal. If delegation cap is reached there will be no waiting list (at least in the first version of the DSC) so new delegations will be rejected.

  • remove inactive nodes (removeNodes([]BLSPublicKey))

  • stake: (stakeNodes([]BLSPublicKey)) activate a set of nodes. The SP as contract owner can activate the nodes by sending a transaction to its DSC, which will further call the Staking Smart Contract (SSC) - recall from Figure 1 that DSC calls the ASC (Auction Smart Contract that keeps the data per staking provider: the total stake amount, total unstaked, number of nodes, list of nodes), which further calls the SSC. The call to activateNodes will pay for the gas which is sent from the DSC to the SSC. The staking transaction will consist of the BLS public keys for all the nodes and the address of the DSC (the reward address = address of the DSC).The collected tokens are already in SSC (they are sent at every delegate), the SSC will activate the nodes according to how much was stake is in the account (if there is still enough room in the SSC) and will generate rewards at each end of epoch. The SP’s DSC becomes the sole owner of those nodes and the funds in the SSC. Any delegator can unJail. Only the SP can unStake and unBond those nodes from the SSC.

  • unStake: (unStakeNodes([]BLSPublicKey)) - deactivate a set of nodes and requests from the ASC. This function can be called by the SP as the contract owner as he might want to change the keys of those nodes.

  • unBond: (unBondNodes([]BLSPublicKey)) - the actual withdrawal of the nodes previously unstaked (after min. 10 epochs).

  • unJail (unJailNodes([]BLSPublicKey)) - The rating of a node is an integer value between 0 and 100, inclusively. A node that is offline or not able or willing to produce new blocks or sign blocks, will have its rating decrease and if it goes below 10 it will be jailed meaning that the node will be no longer be eligible for being selected in the consensus group or as a block proposal and therefore no rewards are earned by that node. For a node with rating below the 10 to be re-considered to be put back on the list of eligible validators, a special unJail transaction (resetRating) has to be sent to the metachain, and validated. In order to incentivize the inclusion of this transaction, the node must include a resetRatingFee as part of their transaction, which will be awarded the block proposer that includes it. The current fee is 0.1% of the stake per node (0.1% x 2500 eGold = 2.5 eGold). unJail is an open function which can be called by any delegator. It is their choice to call or not. But it is a way to ensure that tokens will never be blocked. The fee is paid by the caller.

Delegator

Any number of eGold holders can participate in staking indirectly by delegating their eGold to existing SPs, usually professional staking-as-a-service providers, that choose to accept delegations. An eGold holder indicates which SP candidate they trust, and puts some eGold at stake to support their delegation. If one or more of the nodes of the SP chosen are elected as validators in an epoch, they will share with them any economic rewards or punishments, proportional to their delegated stake. Delegating eGold is a way of investing one's eGold, and contributing to the security of the system. The larger the total amount of eGold staked, the higher the system security, thanks to the increased amount of stake needed by an adversary to get any nodes elected as validators.

The rewards earned by a delegator are assigned as claimable at the start of each epoch for the last epoch, basically every 24 hours. Delegation rewards need to be manually claimed by the delegator at their own choosing. The unclaimed rewards are adding up and they can be claimed at any point in time. This means that there is no compounding of the delegated funds as it has to be done manually by the user. On the other hand, the delegation rewards that are not claimed, in some jurisdictions, are perceived as deferred earnings and are not taxable until they are claimed. Keep in mind that claiming the rewards involves a DSC transaction and some fees are involved (it might not make sense to claim rewards every 24 hours because of this fee). Also, these rewards that need to be claimed, once claimed they are fully unlocked.

If a user decided to withdraw from the DSC this process involves 2 steps: Un-delegate (unDelegate(value)) - a transaction which “tells” the DSC that the delegator wants a specific amount (all or just a part) to be withdrawn from delegation. This deactivates a set of nodes and requests from the ASC the given amount of funds to be unstaked if there is more funds requested than the extra top-up by calling unStakeTokensWithNodes(value). This function is called automatically when a delegator unstakes funds. After the unStake function is called, funds might still be locked for delegation several epochs, depending on system load ratio. For this reason, funds will remain locked in the ASC for 10 epochs. After 10 epochs passed, DSC should call the unBond function to actually retrieve the funds. When funds are unstaked, no nodes management action is needed. If funds remaining in the ASC are not sufficient to run the same number of nodes, fewer nodes will be scheduled for validation the next epoch. If SP does not want node deallocation to happen, he can add missing funds until the end of epoch. The SP can avoid deallocation by keeping always and extra buffer in the top-up part of the ASC. SP can withdraw the deposit when there are no active nodes. The DSC is accepting delegators' stake if the minimum of SP funds are still in the DSC.

Withdraw or un-bond: (withDraw) - after successful un-delegate and 10 epochs have passed the eGold can be withdrawn through a transaction which interacts with the DSC. The DSC will call ASC unBondTokensWithNodes(value) which will give the requested amount. This will return all the withdrawable tokens together for the given delegator.

How to Delegate: (delegate) send appropriate transaction(s) to the DSP(s) corresponding to the desired SP(s) (basically choose the desired SPs and the amounts of eGold to delegate to each). Minimum amount to delegate is 10 eGold.

Claim rewards (claimRewards)- Every user who delegated can claim the currently accumulated rewards for his account. A transaction has to be sent to the DSC with the “claim”. At processing time, it is calculated how many rewards should the account get, by calculating the difference between the last time the claim was called and the current nonce, calculating the total earned rewards by the SP on that time period. The service fee is taken out and the rest is sent to the user. Only the account that delegated can claim the rewards (same public key). A separate claim transaction needs to be sent to the DSC of each separate SP to which a user delegated.

View rewards - Delegator or anyone can view the rewards associated with an address.

Rewards - The separation of nodes from rewards came from the fact that the DSC cannot ensure the number of nodes which are eligible in a certain epoch, thus cannot ensure that a given amount of eGold is earned every day. Moreover, nodes are shuffled in and shuffled out. Thus, the rewards can vary from epoch to epoch. Furthermore, in case the staking-as-a-service provider is malicious or has a set of bad machines or just bad-luck, its rating might get affected, getting jailed, producing even less rewards.

It is up-to the community delegating into such a service to decide when to get out, if the SP is good enough and the terms and conditions are met. The DSC is the narrow waist on which other conditions might be added by different communities. The SP owner of such a DSC can be a DAO which makes their own rules.

Calculate rewards - At the end of each epoch, when the rewards are distributed, the DSC of an SP will get the reward tokens at the rewardAddress for those SP nodes which are in the contract’s address. In order to keep the rewards separately, the total accumulated rewards are saved under a special key in the smart contract’s trie. Then these rewards are claimable by those who delegated in the contract. The SP delegation fees remain in the DSC and can be claimed by the SP as the owner of the DSC. Delegators that claim their rewards will need to pay by themselves the transaction fees (gas) for the claim transaction.

Each epoch the DSC will have the information of total_active, fee and accumulated rewards.

Example: Let’s say after 1 epoch the nodes of the DSC gathered 100 eGold as rewards. As Alice needs some of her rewards immediately, she makes a DSC call to claim all the tokens she is supposed to get: she staked 10% of SP’s total stake and the SP will take 50% for the services of running the nodes. So when Alice will claim her rewards for that epoch she will get 5 eGold. (10% of the gathered rewards is 10 eGold, 50% of it is for services = 5 eGold, the remaining 5 eGold is claimable by Alice).

Constants

  • Registration deposit: 1250 eGold
  • Min. and max. service fee: 0 and 10000 (meaning 0%-100%)
  • Min. delegation: 10 eGold

Variables

TBD

Delegation smart contract guarantees and invariants

Guarantees:

  • The contract can't lose or lock tokens of users.
  • If a user deposited X, the user should be able to withdraw at least X.
  • If a user successfully delegated X, the user can un-stake at least X.
  • The contract should not lock un-staked funds for longer than 10 epochs after un-stake action (except when not enough nodes would remain active and the un-stake is delayed).

It also has inner invariants:

  • The reward fee is a fraction from 0 to 1 inclusive.
  • The SP can't withdraw funds from (other) delegators.
  • The SP can't delete the DSC if there are nodes still staked

NOTE: Guarantees are based on the no-slashing condition. Once slashing is introduced, the contract will no longer provide some guarantees.