Staking Pool Operations
This document describes how to perform staking pool operations. Note that a staking pool can only accept stake from the stake pool owner. You can stake only when you meet the minimum staking requirement.
MINIMUM STAKING REQUIREMENT
The current minimum staking requirement is 1 million APT.
See also the related Delegation Pool Operations instructions to accept stake from multiple delegators in order to reach the minimum staking requirement.
POOL TYPES ARE STATIC
There is no upgrade mechanism for the staking contract to move from a staking pool to a delegation pool. A new
delegation pool must be created.
Initialize a staking pool
TESTNET VS MAINNET
The Aptos CLI commands below target mainnet. Change the --network
value for testnet and devnet.
View the values in Aptos Blockchain Networks to see how profiles can be configured based on the network.
Before initializing a staking pool, ensure that there is an existing owner account with 1 Million APT.
- Initialize the Aptos CLI with a private key from an existing account, such as a wallet, or create a new account.
aptos init --profile mainnet-owner \
--network mainnet
You can either enter the private key from an existing wallet, or create new wallet address.
- Run the following command to initialize the staking pool:
aptos stake create-staking-contract \
--operator <operator-address> \
--voter <voter-address> \
--amount 100000000000000 \
--commission-percentage 10 \
--profile mainnet-owner
- Once the staking pool has been initialized, you can proceed to connect to the Aptos Network.
Perform pool owner operations
Transfer coin between accounts
aptos account transfer \
--account <operator-address> \
--amount <amount> \
--profile mainnet-owner
Switch operator
aptos stake set-operator \
--operator-address <new-operator-address> \
--profile mainnet-owner
Switch voter
aptos stake set-delegated-voter \
--voter-address <new-voter-address> \
--profile mainnet-owner
Add stake
aptos stake add-stake \
--amount <amount> \
--profile mainnet-owner
Increase stake lockup
aptos stake increase-lockup --profile mainnet-owner
Unlock stake
aptos stake unlock-stake \
--amount <amount> \
--profile mainnet-owner
Withdraw stake
aptos stake withdraw-stake \
--amount <amount> \
--profile mainnet-owner
Update commission
aptos move run --function-id 0x1::staking_contract::update_commision \
--args address:<operator_address> u64:<commission_percentage> \
--profile mainnet-owner
Set beneficiary addresses for operators
Staking pool operators can set beneficiary addresses to receive the operator commission earned by the staking pool.
-
The beneficiary addresses can be set by the operator using the following command:
Terminalaptos move run --profile mainnet_operator \ --function-id 0x1::staking_contract::set_beneficiary_for_operator \ --args address:<new_beneficiary_address>
-
To view the beneficiary address set for the operator, use the following command:
Terminalaptos move view --url <REST API for the network> \ --function-id 0x1::staking_contract::beneficiary_for_operator \ --args address:<operator_address>
Any existing unpaid commission rewards will be paid to the new beneficiary. To ensures payment to the current beneficiary, one should first call distribute
before switching the beneficiary. In case an operator operates multiple staking pools, the operator can set one beneficiary for all the staking pools, not a separate one for each pool.
Once the beneficiary address is set, either the operator or the beneficiary can request the operator commission by request_commission
.
Checking your stake pool information
Before you proceed, see Validation on the Aptos blockchain for a brief overview.
To check the details of your stake pool, run the below CLI command with the get-stake-pool
option by providing the --owner-address
and --url
fields.
The below command is for an example owner address e7be097a90c18f6bdd53efe0e74bf34393cac2f0ae941523ea196a47b6859edb
.
For testnet or devnet --url
field values, see Aptos Blockchain Networks.
aptos node get-stake-pool \
--owner-address e7be097a90c18f6bdd53efe0e74bf34393cac2f0ae941523ea196a47b6859edb \
--profile mainnet-operator
Example output:
{
"Result": [
{
"state": "Active",
"pool_address": "25c3482850a188d8aa6edc5751846e1226a27863643f5ebc52be4f7d822264e3",
"operator_address": "3bec5a529b023449dfc86e9a6b5b51bf75cec4a62bf21c15bbbef08a75f7038f",
"voter_address": "3bec5a529b023449dfc86e9a6b5b51bf75cec4a62bf21c15bbbef08a75f7038f",
"pool_type": "StakingContract",
"total_stake": 100525929489123,
"commission_percentage": 10,
"commission_not_yet_unlocked": 15949746439,
"lockup_expiration_utc_time": "2022-10-07T07:12:55Z",
"consensus_public_key": "0xb3a7ac1491b0165f08f136c2b02739846b6610084984d5298c2983c4f8e5553284bffca2e3fe2b99167da82717501732",
"validator_network_addresses": [
"/ip4/35.91.145.164/tcp/6180/noise-ik/0xeddf05470520af91b847f353dd804a04399e1213d130a4260e813527f2c49262/handshake/0"
],
"fullnode_network_addresses": [],
"epoch_info": {
"epoch": 594,
"epoch_interval_secs": 3600,
"current_epoch_start_time": {
"unix_time": 1665087178789891,
"utc_time": "2022-10-06T20:12:58.789891Z"
},
"next_epoch_start_time": {
"unix_time": 1665090778789891,
"utc_time": "2022-10-06T21:12:58.789891Z"
}
}
}
]
}
Description of output fields
state
- ”Active”: Validator is already in the validator set and proposing.
- ”Pending_active”: Validator will be added to the validator set in the next epoch. **Do not try to join the validator set again before the arrival of next epoch, or else you will receive an error. **
pool_address
- Use this “pool_address” (not the operator address) in you
validator.yaml
file. If you mistakenly used the operator address, you will receive the message: “Validator not in validator set”.
commission_percentage
-
This can be set only by the stake pool owner. Operator receives the “commission_percentage” of the generated staking rewards. If you request the commission (you can do so by running the command
aptos stake request-commission
), then at the end of thelockup_expiration_utc_time
the commission part of the rewards will go to the operator address while the rest will stay in the stake pool and belong to the owner. Here “the commission part of the rewards” means the value of commission_not_yet_unlocked.For example, in a scenario with a lock-up of one month, you call
aptos stake request-commission
every month. This will pay out the commission that was accrued during the previous month but only when unlocked at the end of the previous month. Regardless of how often you runaptos stake request-commission
during the month, the commission is only paid out upon the completion oflockup_expiration_utc_time
.COMPOUNDING
Note that if you do not request commission for multiple months, your commission will accrue more due to compounding of the commission_percentage during these months.
commission_not_yet_unlocked
- The amount of commission (amount of APT) that is not yet unlocked. It will be unlocked at the
lockup_expiration_utc_time
. This is the total commission amount available to the operator, i.e., the staking rewards only to the operator. This does not include the staking rewards to the owner.
lockup_expiration_utc_time
- The date when the commission will unlock. However, this unlocked commission will not be auto-disbursed. It will only disburse when the command
aptos stake request-commission
is called again.
epoch_info
- Use Epoch Converter or a similar tool to convert the
unix_time
into human-readable time.
Requesting commission
Either an owner, an operator or the beneficiary of the operator can request commission. You must request commission twice, once before the end of the lockup period and a second time after the lockup period ends, i.e., at the end of lockup_expiration_utc_time, by running the aptos stake request-commission
command. Make sure to provide the operator and the owner addresses. See an example command below:
aptos stake request-commission \
--operator-address 0x3bec5a529b023449dfc86e9a6b5b51bf75cec4a62bf21c15bbbef08a75f7038f \
--owner-address 0xe7be097a90c18f6bdd53efe0e74bf34393cac2f0ae941523ea196a47b6859edb \
--profile mainnet-operator
When you run the aptos stake request-commission
command before the end of the lockup expiration, the command will initiate unlock for any locked commission earned up until that moment in time. The commission will remain in pending_inactive
until the end of the lockup period, will continue to earn rewards until the lockup period expires. The commission will not be withdrawable until after the end of the lockup period, when aptos stake request-commission
is called a second time.
See example below:
Month 1 Day 29, you call the command, it would initiate unlock for 29 days worth of commission.
Month 2, Day 29, if you call the command again, it would disburse the fully unlocked commission from previous month (29 days worth), and initiate commission unlock for Month 1 Day 30 + Month 2 Day 1-29 (30 days worth).
Month 3, Day 29, if you call the commission again, 30 days of commission would be disbursed, and a new batch of commission would initiate unlock.
You can call the command multiple times, and the amount you receive depends on the day when you requested commission unlock previously.
Commission is unlocked when request-commission
is called, the staker unlocks stake, or the staker switches operator.
Checking your validator performance
To see your validator performance in the current and past epochs and the rewards earned, run the below command. The output will show the validator’s performance in block proposals, and in governance voting and governance proposals. Default values are used in the below command. Type aptos node get-performance --help
to see default values used.
aptos node get-performance \
--pool-address <pool address> \
--profile mainnet-operator
Example output:
{
"Result": {
"current_epoch_successful_proposals": 56,
"current_epoch_failed_proposals": 0,
"previous_epoch_rewards": [
"12312716242",
"12272043711",
"12312912674",
"12313011054",
"12313109435",
"12180092056",
"12313305136",
"12313403519",
"12313501903",
"12313600288"
],
"epoch_info": {
"epoch": 68,
"epoch_interval": 3600000000,
"last_epoch_start_time": {
"unix_time": 1665074662417326,
"utc_time": "2022-10-06T16:44:22.417326Z",
"local_time": "Thu Oct 6 16:44:22 2022"
},
"next_epoch_start_time": {
"unix_time": 1665078262417326,
"utc_time": "2022-10-06T17:44:22.417326Z",
"local_time": "Thu Oct 6 17:44:22 2022"
}
}
}
}
Description of fields
current_epoch_successful_proposals
- Successful leader-validator proposals during the current epoch. Also see Validation on the Aptos blockchain for the distinction between leader-validator and the voter-validator.
previous_epoch_rewards
- An ordered list of rewards earned (APT amounts) for the previous 10 epochs, starting with the 10 epoch in the past. In the above example, a reward of 12312716242 APT was earned 10 epochs past and a reward of 12313600288 APT was earned in the most recent epoch. If a reward is 0 for any epoch, then:
- Either the validator was not part of the validator set in that epoch (could have been in either inactive or pending_active validator state), or
- The validator missed all the leader proposals.
Checking the performance for all epochs
To check the performance of all the epochs since the genesis, run the below command. You can filter the results for your pool address with grep
, as shown below:
aptos node analyze-validator-performance \
--analyze-mode detailed-epoch-table \
--profile mainnet-operator \
--start-epoch 0 | grep <pool address>
Tracking rewards
DistributeEvent
is emitted when there is a transfer from staking_contract to
the operator or staker (owner). Rewards can be tracked either by listening to
DistributeEvent
or by using the View function
to call staking_contract_amounts
. This will return accumulated_rewards
and commission_amount
.