Skip to content

Delegated Staking

Overview

The following steps outline the creation of a staking pool with a single validator node.


Prerequisites

Clone the delegated staking repository or pull the main branch if you have already cloned it.

To deploy and interact with staking contracts via the CLI, use the provided Forge scripts. Follow these steps before proceeding with the deployment:

  1. Install Foundry: Follow the official link for foundry installation.

  2. Install OpenZeppenlin Contracts:

    forge install OpenZeppelin/openzeppelin-contracts-upgradeable --no-commit
    forge install OpenZeppelin/openzeppelin-contracts --no-commit
    

  3. Set the RPC URL:
    export FOUNDRY_ETH_RPC_URL=http://localhost:4202
    
  4. Set the Private Key:
    export PRIVATE_KEY=0x...
    
    PRIVATE_KEY refers to the staking pool contract owner's private key.

Step 1: Contract Deployment

Choose which variant of the staking contract to deploy:

Deploying NonLiquidDelegation Contract

forge script script/Deploy.s.sol --broadcast --legacy --sig "nonLiquidDelegation()"

Example output:

  Signer is 0x15fc323DFE5D5DCfbeEdc25CEcbf57f676634d77
  Proxy deployed: 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2
  Implementation deployed: 0x7C623e01c5ce2e313C223ef2aEc1Ae5C6d12D9DD
  Owner is 0x15fc323DFE5D5DCfbeEdc25CEcbf57f676634d77
  Upgraded to version: 0.3.4

Deploying LiquidDelegation Contract

forge script script/Deploy.s.sol --broadcast --legacy --sig "liquidDelegation(string,string)" Name Symbol
where Name and Symbol represent your Liquid Staking Token (LST).

Example output:

  Signer is 0x15fc323DFE5D5DCfbeEdc25CEcbf57f676634d77
  Proxy deployed: 0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2
  Implementation deployed: 0x7C623e01c5ce2e313C223ef2aEc1Ae5C6d12D9DD
  Owner is 0x15fc323DFE5D5DCfbeEdc25CEcbf57f676634d77
  Upgraded to version: 0.3.4

Step 2: Contract Configuration

Configure the validator’s commission rate (e.g., 10%):

forge script script/Configure.s.sol --broadcast --legacy --sig "commissionRate(address payable, uint16)" <DELEGATION_CONTRACT_PROXY_ADDRESS> 1000

You can find DELEGATION_CONTRACT_PROXY_ADDRESS in the output of step 1.

Expected output:

  Running version: 0.3.4
  Commission rate: 0.0%
  New commission rate: 10.0%

Step 3: Validator Addition

Follow one of the approaches below, depending on whether you have already deposited the required stake with your validator node or you need delegations to accumulate enough stake to deposit the required stake.

Scenario 1: Node with Deposited Stake

If you are operating a validator node with the required stake already deposited, execute the following steps:

  1. Set the Control Address:
    cast send --legacy --private-key <0x...> \
    0x00000000005a494c4445504f53495450524f5859 "setControlAddress(bytes,address)" \
    <BLS_PUBLIC_KEY> \
    <DELEGATION_CONTRACT_PROXY_ADDRESS>
    
    here --private-key <0x...> refers to the private key previously used to deposit stake for the validator node. Example:
    cast send --legacy --private-key 0x... \
    0x00000000005a494c4445504f53495450524f5859 "setControlAddress(bytes,address)" \
    0x92fbe50544dce63cfdcc88301d7412f0edea024c91ae5d6a04c7cd3819edfc1b9d75d9121080af12e00f054d221f876c \
    0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2
    
  2. Join the Staking Pool:
    cast send --legacy --private-key $PRIVATE_KEY \
    <DELEGATION_CONTRACT_PROXY_ADDRESS> "joinPool(bytes,address)" \
    <BLS_PUBLIC_KEY> \
    <CONTROL_ADDRESS>
    
    Example:
    cast send --legacy --private-key $PRIVATE_KEY \
    0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 "joinPool(bytes,address)" \
    0x92fbe50544dce63cfdcc88301d7412f0edea024c91ae5d6a04c7cd3819edfc1b9d75d9121080af12e00f054d221f876c \
    0xe0c6f3d59b8cda6ce4fd66418212404a63ad8517
    
    The CONTROL_ADDRESS was generated when depositing the stake required of validators. For details, refer to the staking.md.

Scenario 2: Node Without Deposited Stake

If you are operating a node that does not yet have the required stake deposited, and you do not own the minimum ZIL stake required of validators, proceeding with step 4 will enable your contract to collect the delegated stake you need to deposit with your validator node. Once the stake delegated to the contract plus your ZIL balance as the contract owner exceeds the required minimum, you can add your fully synced node to the staking pool and activate it as a validator by executing:

cast send --legacy --value <YOUR_ZIL>ether --private-key $PRIVATE_KEY \
<DELEGATION_CONTRACT_PROXY_ADDRESS> "depositFromPool(bytes,bytes,bytes)" \
<BLS_PUBLIC_KEY> \
<VALIDATOR_REGISTRATION_SIGNATURE> \
<VALIDATOR_BLS_SIGNATURE>
Example: If your contract has collected 8M ZIL from delegators but is still short of another 2M ZIL, you can complete the deposit by transferring the remaining 2M ZIL out of your balance.
cast send --legacy --value 2000000ether --private-key $PRIVATE_KEY \
0x7A0b7e6D24eDe78260c9ddBD98e828B0e11A8EA2 "depositFromPool(bytes,bytes,bytes)" \
0x92fbe50544dce63cfdcc88301d7412f0edea024c91ae5d6a04c7cd3819edfc1b9d75d9121080af12e00f054d221f876c \
0x002408011220d5ed74b09dcbe84d3b32a56c01ab721cf82809848b6604535212a219d35c412f \
0xb14832a866a49ddf8a3104f8ee379d29c136f29aeb8fccec9d7fb17180b99e8ed29bee2ada5ce390cb704bc6fd7f5ce814f914498376c4b8bc14841a57ae22279769ec8614e2673ba7f36edc5a4bf5733aa9d70af626279ee2b2cde939b4bd8a


Step 4: Staking Pool Registration

Share the from step 1 with the Zilliqa team to allow users to delegate ZIL to your staking pool on the new staking portal.


Summary

By following these steps, you have successfully deployed and configured a Non-Liquid Staking Pool or a Liquid Staking Pool, and added a validator node to it. ZIL holders who delegate to the pool will earn rewards or see their liquid staking token's value increase, and you will receive a commission on the delegated amounts.