# Staking Pool Operations

This document describes how to perform [staking](https://aptos.dev/en/network/blockchain/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.

{% hint style="info" %}
**MINIMUM STAKING REQUIREMENT**\
The current minimum staking requirement is 1 million APT.
{% endhint %}

See also the related Delegation Pool Operations instructions to accept stake from multiple delegators in order to reach the minimum staking requirement.

{% hint style="info" %}
**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.
{% endhint %}

### Initialize a staking pool

{% hint style="info" %}
**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](https://aptos.dev/en/network/nodes/networks) to see how profiles can be configured based on the network.
{% endhint %}

Before initializing a staking pool, ensure that there is an existing owner account with 1 Million APT.

1. Initialize the [Aptos CLI](https://aptos.dev/en/build/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.

2. 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
```

3. Once the staking pool has been initialized, you can proceed to [connect to the Aptos Network](https://aptos.dev/en/network/nodes/validator-node/connect-nodes/connect-to-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:

```
aptos 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:

```
aptos 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

{% hint style="info" %}
Before you proceed, see [Validation on the Aptos blockchain](https://aptos.dev/en/network/blockchain/staking#validation-on-the-aptos-blockchain) for a brief overview.
{% endhint %}

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`.

{% hint style="info" %}
For testnet or devnet `--url` field values, see [Aptos Blockchain Networks](https://aptos.dev/en/network/nodes/networks).
{% endhint %}

```
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 the `lockup_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 run `aptos stake request-commission` during the month, the commission is only paid out upon the completion of `lockup_expiration_utc_time`.

{% hint style="info" %}
**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.
{% endhint %}

**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](https://www.epochconverter.com/) 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:

{% hint style="info" %}
aptos stake request-commission\
\--operator-address 0x3bec5a529b023449dfc86e9a6b5b51bf75cec4a62bf21c15bbbef08a75f7038f\
\--owner-address 0xe7be097a90c18f6bdd53efe0e74bf34393cac2f0ae941523ea196a47b6859edb\
\--profile mainnet-operator
{% endhint %}

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 <a href="#checking-your-validator-performance" id="checking-your-validator-performance"></a>

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](https://aptos.dev/en/network/blockchain/staking#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 <a href="#checking-the-performance-for-all-epochs" id="checking-the-performance-for-all-epochs"></a>

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 <a href="#tracking-rewards" id="tracking-rewards"></a>

`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](https://aptos.dev/en/build/apis#reading-state-with-the-view-function) to call `staking_contract_amounts`. This will return `accumulated_rewards` and `commission_amount`.

<br>
