Zearn Docs
  • Zearn Overview
    • Overview
    • Administration
    • Achitecture
    • Roadmap
  • How Zearn Works
    • Zearn Stake Tutorial
    • Fees
    • Guides
    • Contracts
    • Integrating stZETA
    • Audits
    • Deployed Contracts
  • ZEARN.FUN OVERVIEW
    • Overview
    • MemeCoin Explanation
    • Zearn.fun Tutorials
    • Fees
  • Resources
    • Media Kit
    • FAQ
    • Bug Bounty
    • Meet Our Team
    • Opportunities
    • Social Media
    • Privacy Policy
    • Terms of Use
Powered by GitBook
On this page
  • stZETA contract
  • Access Control List
  • User Interactions
  • Minting stZETA
  • Example
  • Delegate to Validators
  • Manage Withdrawals
  • Distribute Rewards
  • withdrawTotalDelegated
  • ValidatorShare Behaviour
  • Manage reward fees:
  • ValidatorShare API
  • UnstZETA
  • Operator contract
  • Manage Operators
  • Stake an operator
  • Join
  • Unstake an Operator
  • Remove an Operator
  • Top Up Heimdall Fees
  • Unjail
  • Restake
  • Update Signer Public Key
  • Unstake Claim
  • Claim Fee
  • Update Operator Commision Rate
  • Set Stake Amount And Fees
  • Validator Factory
  • create
  • remove
  1. Zearn Overview

Achitecture

PreviousAdministrationNextRoadmap

Last updated 1 year ago

The Zearn architecture has 3 main parts:

  • stZETA contract

  • UnstZETA contract

  • NodeOperator contract (Coming soon)

stZETA contract

The stZETA contract is an ERC20 token contract that carries out the following operations:

  • User interaction

  • Reward Distribution

  • Manage withdrawals

  • Manage reward fees

  • Delegate to validators

  • Mint and burn NFTs

Access Control List

The stZETA contract uses OpenZeppelin AccessControl to manage permissions.

User Interactions

A user can interact only with the Zearn contract to:

  • Submit ERC20 ZETA

  • Request withdrawals

  • Claim withdrawals

  • Call ERC20 functions

Users can easily acquire stZETA by calling the submit function within the stZETA contract and specifying the amount they wish to delegate. This action will automatically exchange their ZETA for stZETA.

Minting stZETA

The calculation of the total stZETA a user receives when delegating their ZETA tokens proceeds as follows:

sharePerUser = submittedZeta * totalShares / totalPooledZeta

The totalPooledZeta represents the sum of buffered tokens (those submitted by the user but yet to be delegated) and the total amount already delegated.

totalPooledZeta = totalBufferedZeta + totalDelegatedZeta

Example

Case 1

Initial states

totalShares
0

totalPooledZeta

0

UserA submit

submit —> 1000 ZETA

Gets —> 1000 stZETA

Update states

totalShares
1000

totalPooledZeta

1000

Users Shares

User
stakeRatio = userShares / totalShares
userZeta = stakeRatio * totalPooledZeta

1

1 = 1000 / 1000

1000 = 1 * 1000

Case 2

UserB submit

submit —> 500 ZETA

Gets —> 500 * 1000 / 1000 = 500 stZETA

Update states

totalShares
1500

totalPooledZeta

1500

Users Shares

User
stakeRatio = userShares / totalShares
userZeta = stakeRatio * totalPooledZeta

1

0.66 = 1000 / 1500

1000 = 0.66 * 1500

2

0.33 = 500 / 1500

500 = 0.33 * 1500

Case 3

The system was slashed —> -100 ZETA

Update states

totalShares
1500

totalPooledZeta

1500 - 100 = 1400

Users Shares

User
stakeRatio = userShares / totalShares
userZeta = stakeRatio * totalPooledZeta

1

0.66 = 1000 / 1500

933.33 = 0.66 * 1400

2

0.33 = 500 / 1500

466.66 = 0.33 * 1400

Case 4

UserC submit

submit —> 500 ZETA

Gets —> 500 * 1500 / 1400 = 535.71 stZETA

Update states

totalShares
2035.71

totalPooledZeta

1900

Users Shares

User
stakeRatio = userShares / totalShares
userZeta = stakeRatio * totalPooledZeta

1

0.4912 = 1000 / 2035.71

933.33 = 0.4912 * 1900

2

0.2456 = 500 / 2035.71

466.66 = 0.2456 * 1900

3

0.2631 = 535.71 / 2035.71

500 = 0.2631 * 1900

Case 5

The system accumulates reward —> +200 ZETA

Update states

totalShares
2035.71

totalPooledZeta

1900 + 200 = 2100

Users Shares

User
stakeRatio = userShares / totalShares
userZeta = stakeRatio * totalPooledZeta

1

0.4912 = 1000 / 2035.71

1031.52 = 0.4912 * 2100

2

0.2456 = 500 / 2035.71

515.76 = 0.2456 * 2100

3

0.2631 = 535.71 / 2035.71

552.62 = 0.2631 * 2100

When the system experiences a reduction, the overall pooled ZETA decreases. However, it rebounds when a user contributes ZETA again or when the system receives rewards.

Delegate to Validators

The stZETA contract is used to delegate tokens to validators.Our delegation process is driven by the real buffered ZETA within the stZETA contract. Once we hit the minDelegationAmount, we begin delegating to all staked operators. Each operator has a maxDelegateLimit, a value determined by the DAO. For instance, a trusted operator would have a higher limit, while a less trusted validator might have a lower one. This maxDelegateLimit allows us to distribute tokens effectively amongst operators.

Manage Withdrawals

The withdrawal employs the fresh validatorShare exit API. This gives us a nonce that can be utilized to associate each user request with this specific nonce. The ZETA contract keeps tabs on each validatorShare nonce, which will step up each time there's a new withdrawal request.

  1. Request Withdrawal: In the event a user decides to withdraw their ZETA tokens from the system, a fresh ERC721 token is created and linked to this request. The owner has the flexibility to trade this token, sell it, or use it to reclaim their ZETA tokens.

    1. The user requests a withdrawal.

    2. Mint an NFT and map its ID with the request.

    3. Store the request nonce of the validatorShare and validatorShare address.

    4. Call the sellVoucher_new function

  2. Claim tokens:

    1. The user calls the claim token function and passes the tokenId.

    2. Check if the msg.sender is the owner of this NFT.

    3. Call the claim unstake tokens function on the validatorShare contract.

    4. Transfer tokens to the user.

    5. Burn the NFT.

Distribute Rewards

ZETA tokens are gathered and housed within the stZETA contract in response to two specific events:

Whenever a user initiates a withdrawal request, the validatorShare contract dutifully transfers the respective rewards.

Scheduled job (explained below)

TOTAL_REWARDS = accumulated rewards on Zearn + accumulated rewards on all validators

We're set to allow operators a maximum stake of 10 ZETA tokens. Any accumulated rewards on all validator sides will be disregarded. Our oracle daemon will handle reward distribution. Regular checks will be conducted to ensure the amount is above a lower limit, which can be adjusted as needed. Once this is confirmed, stZETA works out the share for Node Operators and the treasury and immediately transfers tokens to them. The remaining ZETA tokens are then added to the buffer and re-delegated, which increases the totalPooledZETA value. The staking rewards are divided as follows: 5% to Zearn DAO treasury, 5% to Node Operators, and the bulk, 90%, is returned to the stZETA value via re-delegation.

Rewards for operators are allocated among all staked operators based on a specific ratio. A validator who has not been slashed in the previous period receives a ratio of 100%. However, if a validator has been slashed, their ratio drops to 80% of their total reward portion, with the remaining percentage distributed among the other validators.

withdrawTotalDelegated

When an operator is unstaked, the nodeOperator contract triggers the withdrawTotalDelegated function. This function claims all the delegated ZETA from the unstaked validator. Subsequently, an NFT token is minted and linked to this request. Later on, a scheduled task can call claimTokens2stZETA to withdraw the ZETA from the validatorShare.

ValidatorShare Behaviour

When a user initiates a withdrawal, the validatorShare contract automatically handles the transfer of all accumulated rewards. The same process also applies when new vouchers are purchased. The primary concept here is to regard all tokens that have not been submitted (not buffered) through the submit function as rewards that are due for distribution.

Manage reward fees:

We can manage the rewards fees using the stZETA contract.

ValidatorShare API

The stZETA implements the validatorShare contract API

  1. BuyVoucher_new: buy shares from a validator link.

  2. SellVouchernew: sell an amount of shares link. Also, it has a good feature that allows us to track each sell request using a nonce.

  3. unstakeClaimTokens_new: claim the token by a nonce link.

  4. getTotalStake: get the total staked amount link.

  5. getLiquidRewards: get the accumulated rewards link

UnstZETA

The UnstZETA contract, an ERC721 contract, is utilized by the stZETA contract to handle withdrawal requests.Each time a user triggers the requestWithdraw function within the stZETA contract, a new NFT is created and linked to the request.As an NFT owner, a user can:

  • Retrieve tokens from the withdrawal request

  • Transfer the NFT to another individual, who can then make a claim

  • Authorize another individual to make a claim

This ERC721 contract has slight modifications, allowing it to return a list of tokens owned by an address through the owner2Tokens public mapping. The same applies to obtaining the list of approved tokens through the address2Approved mapping.

Operator contract

Manage operatorsThe validator contract plays a key role in staking on the ZetaChain stake manager. For each operator, a new validatorProxy contract is generated when the addOperator function is called. This validatorProxy acts as the owner of the validator on the ZetaChain stakeManager. It enables the operator's owner to interact with the stakeManager API to:

  • Stake a validator using stakeFor.

  • Unstake a validator using unstake.

  • Top up Heimdall fees for a validator using topUpForFee.

  • Check the total staked by a validator using validatorStake.

  • Restake amount using restake.

  • Access validator share contract using getValidatorContract.

  • Update signer pubkey using updateSIgner.

  • Withdraw Heimdall fees using claimFee.

  • Change commission using updateCommisionRate.

  • Withdraw rewards using withdrawRewards.

Manage Operators

  1. Add an operator

    1. An Operator expresses interest in participating in the UnstZETA protocol.

    2. The DAO conducts a vote to consider the inclusion of the new operator. If the vote for inclusion is successful, the Node Operator becomes active:

      1. A fresh validator contract is established.

      2. The status is set to NotStaked.

      3. A default max delegation value is assigned, indicating the system will delegate this amount (at most) whenever the delegate function is triggered.

Each operator owner is able to engage with their operator using the reward address to perform the following actions:

  • stake

  • join

  • unstake

  • topUpHeimdallFees

  • unjail

  • restake

  • update signer pub key

  • unstake claim

  • claim fee

Stake an operator

  1. The operator calls the stake function, including the amount of ZETA and heimdallFees.

  2. The operator is switched to staked status and becomes ready to accept delegation.

Join

  1. Allows already staked validators to join the UnstZETA protocol.

  2. They have first to approve the NFT token to the specific validatorProxy contract.

  3. Call this function to join the system.

Unstake an Operator

During the unstaking process of an operator, the NodeOperator contract interacts with the stZETA contract. Subsequently, the stZETA contract engages with the validatorShare contract to withdraw the total delegated ZETA tokens. After a specified withdrawal delay, the Zearn contract is eligible to claim these tokens. This final step of claiming tokens can be automated using a cron job.

Remove an Operator

The final step in the process is the removal of an operator. This occurs after the operator has unstaked and claimed their staked tokens. The DAO has the ability to invoke this function, which results in the operator's removal and deletion of the validatorProxy contract.

Top Up Heimdall Fees

A validator can replenish the Heimdall fees that are consumed by the Heimdall and Bor nodes during the validation of new blocks.

Unjail

Allows a validator to switch his status from locked to active.

Restake

Allows a validator to stake more ZETA, by default this feature is disabled.

Update Signer Public Key

Allows the operator to update the Signer Public key used by the heimdall.

Unstake Claim

Allows the operator owner to claim his staked ZETA tokens.

Claim Fee

Allows the operator owner to claim his heimdall fees.

Update Operator Commision Rate

Update the operator's commission rate.

Set Stake Amount And Fees

Define the minimum and maximum amounts, along with Heimdall fees, that an operator can apply towards staking or topping up Heimdall fees.

Validator Factory

The Validator Factory is leveraged to roll out new ValidatorProxy instances, which are subsequently added to a validator array.

create

  • permission:

    • OPERATOR

  • description:

    • Creates a new ValidatorProxy and appends it to array of validators

remove

  • permission:

    • OPERATOR

  • description:

    • Removes a ValidatorProxy determined by its address from the array of validator