Smart contract operations


Security Audit of Smart Contract

The smart contracts have been audited by Quantstamp. A copy of the security audit report can be found in our Github repository or on Quantstamp certification website.

Enrollment Into the Smart Contract

We will require you to provide us the following information via the communication channel we have established with you

  • Zilliqa address where you will deposit/withdraw stake and receive rewards*
  • Your IP address
  • Your port(s) if you have changed any of default ports
caution

We highly recommend to use a secured keypair for depositing stake, withdrawing stake and withdrawing reward. Please do not reuse the keypair you use for running your staked seed node.

Upon providing the information, the Zilliqa team will proceed to add your staked seed node information into the smart contract and informed you once it is done.

Getting Testnet $ZIL (Testnet only)

To get you started, let us know the amount of testnet $ZIL you wish to get and we will send to your address. We recommend the following values

$ZILPurpose
50,000 testnet $ZILFor depositing stake
5,000 testnet $ZILFor gas fees

Also, if you need a small amount of testnet $ZIL from time to time, you can go to our Testnet Faucet to request for it.

Introduction to Staked Seed Node Smart Contract

The following guide will use Zilliqa ZLI and SDK as an example for interacting with the smart contract.

tip

For ZLI installation and initialisation of the wallet in ZLI, please refer to the README documentation at https://github.com/Zilliqa/zli

The staked seed node smart contract will be used in the following ways:

  • Allows addition/removal of staked seed node
  • Allows for deposit of stake reward to staked seed node operator
  • Allows staked seed node operator to deposit stake deposit
  • Allows staked seed node operator to withdraw stake deposit
  • Allows staked seed node operator to withdraw stake reward

For staked seed node operators, a number of smart contract transition is available for them, namely:

  • stake_deposit()
  • withdraw_stake_rewards()
  • withdraw_stake_amount()

Smart Contract Information

We have two smart contracts, namely proxy and ssnlist. Proxy contract stores the implementation address of ssnlist and forwards all calls to the logic contract, ssnlist.

As such, any user who wishes to interact with the contract, should interact with proxy contract only.

TypeAddress
proxyBech32: zil135gsjk2wqxwecn00axm2s40ey6g6ne8668046h
Base16: 0x8d1109594e019d9c4defe9b6a855f92691a9e4fa
ssnlistBech32: zil106pzq6thrzhxq2xuepa6807pmkrsepqdf0yrd6
Base16: 0x7e8220697718ae6028dcc87ba3bfc1dd870c840d
ParametersValue
Min stake10k
Max stake100k
Overall contract max stake1M
Reward cycle3 DS blocks
Notice

Please use proxy contract address if you need to call the smart contract.

SSN Address and Key Pair Management

Each staked seed node registered in the contract is associated with a Zilliqa mainnet address. This address is used to both deposit and withdraw funds as well as withdraw the rewards using the smart contract transitions listed above. Operators should take care to exercise whatever policies are in place in their organizations for managing the key pair associated with this address.

Key management

The key pair used for staking the seed node has no relation to the operational key pair used by the seed node for communicating with other nodes in the network (i.e., the key pair contained in the mykey.txt file generated when launching the seed node). It is highly recommended not to use a single key pair for both purposes.

Stake Deposit

Why a Stake Deposit is Required

Having each operator deposit an amount in the contract ensures that rewarding is done on the basis of the staked seed node providing its API service uninterrupted. This is achieved by staking (the proportion of “skin in the game”). By depositing $ZILs, a seed node operator shows its commitment towards providing the seed node service. Without this "skin in the game", a seed node operator could decide to stop the service at will and may impact the ecosystem and the end-users.

Stake Deposit Process

Currently, our rewarding cycle is paid out once every 15 DS epochs. To deter abuse or gaming of the reward cycle, the stake deposit will first be entered as a buffered deposit. At the next multiple of 15 DS epoch, the buffered deposit will be transferred to the stake deposit. From then on, the stake deposit will be eligible for rewards.

CLI way to deposit stake amount

zli contract call -a <proxy contract_address> -t stake_deposit -r "[]" -m <funds_in_Qa> -f true

Example:

zli contract call -a 0123456789012345678901234567890123456789 -t stake_deposit -r "[]" -m 10000000000000 -f true

SDK sample code

LanguageLink to sample code
NodeJSstake_deposit.js
JavastakeDeposit()

How to Check the Current Stake Deposit and Stake Buffered Amount?

The current stake deposit and stake buffered amount can be retrieved by querying the staking contract state:

curl -d '{"id":"1", "jsonrpc": "2.0", "method": "GetSmartContractState", "params":["<staking_contract_address>"]}' -H "Content-Type: application/json" -X POST "https://api.zilliqa.com"

In the response, under “ssnlist: {...}”, look for your staked seed node address. The first numeric value listed is the current stake deposit, and the second numeric value is the amount of accrued rewards.

Example of stake deposit for a particular ssn address:

{
...
...
"ssnlist" : {
"0xced263257fa2d12ed0d1fad74ac036162cec7989" : {
"arguments" : [
{
"argtypes" : [],
"arguments" : [],
"constructor" : "True"
},
"1000000001", ← stake deposit
"0", ← reward amount
"devapiziiliqacom",
"ziiliqacom",
"0" - stake buffered amount
],
"argtypes" : [],
"constructor" : "Ssn"
}
},
...
...
}
}

SDK sample code for getting stake buffered amount

LanguageLink to sample code
NodeJSget_stake_buffered_amount.js
JavagetStakeBufferedAmount()

SDK sample code for getting stake amount (non-buffered)

LanguageLink to sample code
NodeJSget_stake_amount.js
JavagetStakeAmount()

Withdrawal of Stake Deposit

What Happens When the Stake Deposit is Withdrawn?

For partial withdrawal, you will need to ensure that your stake deposit is larger than the minimum stake amount (10,000,000 ZIL) for the withdrawal to be successful.

For full withdrawal, with the rewards not yet fully withdrawn, your staked seed node will become inactive. It can be reactivated by doing another stake deposit into the contract.

For full withdrawal, with the rewards also fully withdrawn, your staked seed node will be removed from the list of staked seed nodes. The Zilliqa team will need to re-add your seed node into the contract should you wish to participate once again in staking.

CLI Way to Withdraw Stake Deposit

Zli command: withdraw_stake_amount

zli contract call -a <proxy contract_address> -t withdraw_stake_amount -r "[{\"vname\":\"amount\",\"type\":\"Uint128\",\"value\":\"<amount>\"}]" -f true

Example:

zli contract call -a 0123456789012345678901234567890123456789 -t withdraw_stake_amount -r "[{\"vname\":\"amount\",\"type\":\"Uint128\",\"value\":\"500000000000\"}]" -f true
info

Param amount here is expressed in Qa units (1 $ZIL = 1,000,000,000,000 Qa).

SDK sample code

LanguageLink to sample code
NodeJSwithdraw_stake_amount.js
JavawithdrawStakeAmount()

Getting Rewards

How Rewards are Given

In order to be eligible for rewards, the staked seed node must satisfy all of the following criteria:

  1. It must be recognized as an active staked seed node in the staking smart contract.
  2. It must pass the checks for raw data storage requested by the Verifier.
  3. It must pass the checks for servicing API requests by the Verifier.

Rewards are given once every 15 DS epochs. Over a period of a year, it is estimated that the staked seed node will receive approximately 10.42% of the stake deposit as reward, if the staked seed node has an uptime of 100%.

Rewards are not added to the stake deposit; they are stored separately from the stake deposit. When calculating the reward, the Verifier only takes the stake deposit into account. As such, there is no “compounding” effect for the rewards.

Reward Estimator Utility

The reward estimator utility is accessible at https://zilliqa.github.io/staking-calculator-plugin/index.html

Penalty for Rewards

If the staked seed node did not achieve 100% uptime, the reward will be reduced proportionally based on the number of checks passed.

CLI Way to Check Current Rewards

Zli staking reward utility:

zli staking rewards -s ssn_operator -c <proxy contract_address> -a api_endpoint

Example:

zli staking rewards -s 0x53e954391539f276c36a09167b795ab7e654fdb7 -c 343407558c9bb1f7ae737af80b90e1edf741a37a -a https://api.zilliqa.com

SDK sample code

LanguageLink to sample code
NodeJSget_stake_rewards.js
JavagetStakeRewards()

Withdrawing Rewards

Withdraw Reward Process

The withdrawal of the reward process is straightforward. The staked seed node operator will need to only invoke withdraw_stake_rewards() using the operator key, and the reward will be sent to the staked seed node operator address.

For reward withdrawal, with full stake amount already withdrawn, your staked seed node will be removed from the list of staked seed nodes.

CLI Way to Withdraw Current Rewards

zli command: withdraw_stake_rewards

zli contract call -a <proxy contract_address> -t withdraw_stake_rewards -r "[]" -f true

Example:

zli contract call -a 0123456789012345678901234567890123456789 -t withdraw_stake_rewards -r "[]" -f true

SDK sample code

LanguageLink to sample code
NodeJSwithdraw_stake_rewards.js
JavawithdrawStakeRewards()