Skip to content

Commit

Permalink
Merge pull request #86 from 0xPolygon/empieichO-docs-review
Browse files Browse the repository at this point in the history
Update PoS docs - added new section
  • Loading branch information
EmpieichO authored Dec 15, 2023
2 parents 57f99f9 + 74e4149 commit 299f7cc
Show file tree
Hide file tree
Showing 15 changed files with 1,113 additions and 4 deletions.
Binary file added docs/img/pos/staking_manager.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/miden/architecture/state.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
giThe state of the Miden rollup describes the current condition of all accounts and note states. It describes what is currently the case. With its state model, using concurrent off-chain state, Polygon Miden aims to realize private transactions, and execution and state bloat minimization.
The state of the Miden rollup describes the current condition of all accounts and note states. It describes what is currently the case. With its state model, using concurrent off-chain state, Polygon Miden aims to realize private transactions, and execution and state bloat minimization.

Privacy is realized from a UTXO-like state model consisting of notes and nullifiers combined with off-chain execution using zero-knowledge proofs. Execution bloat happens when transactions get re-executed by all participants of the network. State bloat describes the ever growing state stored in blockchain nodes. Polygon Miden addresses these challenges via its state model that enables concurrent off-chain execution and off-chain storage.

Expand Down
2 changes: 0 additions & 2 deletions docs/pos/how-to/operating/validator-node/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Operating a Polygon Validator Node

Operating as a validator on the Polygon Network involves playing a pivotal role in validating transactions within the blockchain. This guide provides details on how to run a Validator Node (including Sentry and Validator components) on the Polygon Network, the responsibilities involved, and the technical and operational aspects to consider.

## Eligibility and responsibilities
Expand Down
60 changes: 60 additions & 0 deletions docs/pos/how-to/operating/validator-node/rewards.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
In Polygon, validators stake their MATIC tokens as collateral to work for the security of the network, and in exchange for their service, earn rewards.

To leverage Polygon's economics, you should either become a validator or a delegator.

To be a validator, you need to **run a full validator** node and stake MATIC.

Also check the [Validator Responsibilities](/pos/design/validator/responsibilities) page.

To be a delegator, you only need to **delegate MATIC to a validator**

## What is the incentive?

Polygon allocates 12% of its total supply of 10 billion tokens to fund the staking rewards. This is to ensure that the network is seeded well enough until transaction fees gain traction. These rewards are primarily meant to jump-start the network, while the protocol in the long run is intended to sustain itself on the basis of transaction fees.

**Validator Rewards = Staking Rewards + Transaction Fees**

This is allocated in a way to ensure gradual decoupling of staking rewards from being the dominant component of the validator rewards.

|Year|Target Stake (30% of circulating supply)|Reward Rate for 30% Bonding|Reward Pool|
|---|---|---|---|
|First|1,977,909,431|20%|312,917,369|
|Second|2,556,580,023|12%|275,625,675|
|Third|2,890,642,855|9%|246,933,140|
|Fourth|2,951,934,048|7%|204,303,976|
|Fifth|2,996,518,749|5%|148,615,670 + **11,604,170**|

Below is a sample snapshot of the expected annual rewards for the first 5 years considering staked supply ranging from 5% to 40% at 5% interval

|% of circulating supply staked|5%|10%|15%|20%|25%|30%|35%|40%|
|---|---|---|---|---|---|---|---|---|
|Annual reward for year|
|First|120%|60%|40%|30%|24%|20%|17.14%|15%|
|Second|72%|36%|24%|18%|14.4%|12%|10.29%|9%|
|Third|54%|27%|18%|13.5%|10.8%|9%|7.71%|6.75%|
|Fourth|42%|21%|14%|10.5%|8.4%|7%|6%|5.25%|
|Fifth|30%|15%|10%|7.5%|6%|5%|4.29%|3.75%|

## Who gets the incentives?

Stakers running validator nodes and stakers delegating their tokens toward a validator that they prefer.

Validators have the option to charge a commission on the reward earned by delegators.

The funds belonging to all stakers are locked in a contract deployed on the Ethereum mainnet.

No validator holds custody over delegator tokens.

## Staking rewards

The yearly incentive is absolute — irrespective of the overall stake or the target bonding rate in the network, the incentive amount is given out as a reward to all signers periodically.

In Polygon, there is an additional element of committing periodic checkpoints to the Ethereum mainnet. This is a major part of the validator responsibilities and they are incentivized to perform this activity. This constitutes a cost to the validator which is unique to a Layer 2 solution such as Polygon. We strive to accommodate this cost in the validator staking reward payout mechanism as a bonus to be paid to the proposer, who is responsible for committing the checkpoint. Rewards minus the bonus is to be shared among all stakers, proposer and signers, proportionally.

## Encouraging the proposer to include all signatures

To avail the bonus completely, the proposer must include all signatures in the checkpoint. Because the protocol desires ⅔ +1 weight of the total stake, the checkpoint is accepted even with 80% votes. However, in this case, the proposer gets only 80% of the calculated bonus.

## Transaction fees

Each block producer at Bor is given a certain percentage of the transaction fees collected in each block. The selection of producers for any given span is also dependent on the validator’s ratio in the overall stake. The remaining transaction fees flow through the same funnel as the rewards which get shared among all validators working at the Heimdall layer.
159 changes: 159 additions & 0 deletions docs/pos/reference/commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
This guide provides a curated list of common commands and Polygon-specific operations essential for node operators. Whether you're setting up a full node, validator node or troubleshooting, these commands will assist you in managing your Polygon PoS environment effectively.

## Frequently used commands for Bor & Heimdall
### Bor

To execute Bor IPC commands, use the following syntax:

```bash
bor attach .bor/data/bor.ipc <command>
```

| IPC Command | RPC Command | Description |
| ----------- | ----------- | ----------- |
| `admin.peers.length` | `curl -H "Content-Type: application/json" --data '{"jsonrpc": "2.0", "method": "net_peerCount", "params": [], "id": 74}' localhost:8545` | Retrieves the number of peers connected to the node. |
| `admin.nodeInfo` | | Provides detailed information about the node. |
| `eth.syncing` | `curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "eth_syncing","params": []}' localhost:8545` | Indicates whether the node is syncing (`true`) or not (`false`). |
| `eth.syncing.highestBlock - eth.syncing.currentBlock` | | Compares the current block of your node to the highest block. |
| `eth.blockNumber` | `curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "eth_blockNumber","params": []}' localhost:8545` | Returns the latest block number processed by the node. |
| `debug.setHead("0x"+((eth.getBlock('latest').number) - 1000).toString(16))` | | Rewinds the blockchain to 1000 blocks prior. |
| `admin.nodeInfo.enode` | | Retrieves the public enode URL of the node. |
| `eth.syncing.currentBlock * 100 / eth.syncing.highestBlock` | | Calculates the remaining percentage for block synchronization. |
| `eth.getBlock("latest").number` | `curl http://YourIP:8545 -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"bor_getSigners", "params":["0x98b3ea"]}'` | Queries the height of the latest Bor block. |
| | `curl http://YourIP:8545 -X POST -H "Content-Type: application/json" --data '{"method":"eth_chainId","params":[],"id":1,"jsonrpc":"2.0"}'` | Retrieves the `chainID`. |

### Heimdall

| Command | Description |
| ------- | ----------- |
| `curl localhost:26657/net_info?` | Returns the number of connected peers using `jq .result.n_peers`. |
| `curl -s localhost:26657/status` | Retrieves Heimdall's current block height using `jq .result.sync_info.latest_block_height`. |
| `curl localhost:26657/net_info` | Queries the node using its moniker with `grep moniker`. |
| `curl -s localhost:26657/status` | Checks if Heimdall is in sync using `jq .result.sync_info.catching_up`. |
| `curl -s localhost:26657/status` | Verifies Heimdall's sync status using `jq .result \| jq .sync_info`. |
| `heimdalld unsafe-reset-all` | Resets the database in case of issues. |
| `curl localhost:26657/status` | Provides comprehensive information about Heimdall. |


## Node management commands

| Description | Command |
| ------------------------------------- | ---------------------------------------------- |
| **Locate Heimdall genesis file** | `$CONFIGPATH/heimdall/config/genesis.json` |
| **Locate heimdall-config.toml** | `/etc/heimdall/config/heimdall-config.toml` |
| **Locate config.toml** | `/etc/heimdall/config/config.toml` |
| **Locate heimdall-seeds.txt** | `$CONFIGPATH/heimdall/heimdall-seeds.txt` |
| **Start Heimdall** | `$ sudo service heimdalld start` |
| **Start Heimdall rest-server** | `$ sudo service heimdalld-rest-server start` |
| **Start Heimdall bridge-server** | `$ sudo service heimdalld-bridge start` |
| **Locate Bor genesis file** | `$CONFIGPATH/bor/genesis.json` |
| **Start Bor** | `sudo service bor start` |
| **Retrieve Heimdall logs** | `/var/log/matic-logs/` |
| **Check Heimdall logs** | `tail -f heimdalld.log` |
| **Check Heimdall rest-server logs** | `tail -f heimdalld-rest-server.log` |
| **Check Heimdall bridge logs** | `tail -f heimdalld-bridge.log` |
| **Check Bor logs** | `tail -f bor.log` |

## Useful configuration commands

### Sync status of Heimdall

To check if Heimdall is synced, run:

```bash
curl http://localhost:26657/status
```

### Latest block height on Heimdall

To check the latest block height on Heimdall, run:

```bash
curl localhost:26657/status
```

### Latest block height on Bor

To check the latest block height on Bor, use:

```bash
curl http://<your ip>:8545 -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "method":"bor_getSigners", "params":["0x98b3ea"]}'
```

### Cleanup: deleting remnants of Heimdall and Bor

**For Linux package:**

```bash
sudo dpkg -i matic-bor
sudo rm -rf /etc/bor
```

**For Binaries:**

```bash
sudo rm -rf /etc/bor
sudo rm /etc/heimdall
```

### Terminate Bor process

**For Linux:**

```bash
ps -aux | grep bor
sudo kill -9 <PID>
```

**For Binaries:**

```bash
cd CS-2003/bor
bash stop.sh
```

### Retrieve latest peer details

To retrieve the latest peer details, run:

```bash
bor attach bor.ipc
admin.peers.forEach(function(value){
console.log(value.enode+',')
})
exit
```

### Stop Heimdall and Bor services

**For Linux packages:**

```bash
sudo service heimdalld stop
sudo service bor stop
```

**For binaries:**

```bash
pkill heimdalld
pkill heimdalld-bridge
cd CS-2001/bor
bash stop.sh
```

### Remove Heimdall and Bor directories

**For Linux packages:**

```bash
sudo rm -rf /etc/heimdall/*
sudo rm -rf /etc/bor/*
```

**For binaries:**

```bash
sudo rm -rf /var/lib/heimdalld/
sudo rm -rf /var/lib/bor
```
50 changes: 50 additions & 0 deletions docs/pos/reference/commit-chain-multisigs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

## Purpose and capabilities

The primary role of multi-signature wallets (multisigs) is to facilitate contract upgrades during the early stages of development. As these contracts become more robust, Polygon plans to:

- Transition from multisigs to governance-controlled proxies.
- Implement timelocks for added security.
- Phase out multisigs entirely in the long term.

**It's important to note that the existing multisigs do not have the capability to censor transactions, including bridge transactions.**

## Active multi-signature wallets

### Ethereum chain multisigs

| Multisig Address | **5/9 Multisig**<br/>`0xFa7D2a996aC6350f4b56C043112Da0366a59b74c` |
|:----------------:|---------------------------------------------------------------------|
| Purpose | To upgrade PoS and staking contracts on Ethereum. |
| Chain | Ethereum |
| Rights | - Update staking contracts for optimizations and upgrades.<br/>- Address unexpected bugs in PoS contracts. |
| Signatories | Quickswap, Curve, Polygon, Horizon Games, Cometh |

### Polygon commitchain multisigs

| Multisig Address | **5/8 Multisig**<br/>`0x355b8E02e7F5301E6fac9b7cAc1D6D9c86C0343f` |
|:----------------:|---------------------------------------------------------------------|
| Purpose | To update custom ChildERC20s on Polygon Commitchain. |
| Chain | Polygon Commitchain |
| Rights | Ability to upgrade custom child contracts. |
| Signatories | Quickswap, Curve, Polygon, Horizon Games, Cometh |

### Custom child ERC20s mapping

| Multisig Address | **4/8 Multisig**<br/>`0x424bDE99FCfB68c5a1218fd3215caFfD031f19C4` |
|:----------------:|---------------------------------------------------------------------|
| Purpose | To enable the mapping of custom ChildERC20s with Mainnet contracts. |
| Chain | Ethereum |
| Rights | Limited to mapping; no access to Child tokens or deposit/withdrawal rights. |
| Signatories | Polygon |

### Permissionless mapping

| Multisig Address | **Permissionless Mapping of Standard ChildERC20 Tokens (No Multisig Required)** |
|:----------------:|--------------------------------------------------------------------------------|
| Purpose | FxPortal supports permissionless token mapping of standard ChildERC20 for any ERC20 token on Ethereum. |
| Chain | Permissionless |
| Rights | Permissionless |
| Signatories | Permissionless |

<sub>*Plans are underway to transition these functions to governance. We are currently exploring options such as Aave's governance contracts and Compound’s timelock contracts.</sub>
106 changes: 106 additions & 0 deletions docs/pos/reference/contracts/delegation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
Polygon supports delegation via validator shares. By using this design, it is easier to distribute rewards and slash with scale (thousands of delegators) on Ethereum contracts without much computation.

Delegators delegate by purchasing shares of a finite pool from validators. Each validator will have their own validator share token. Let's call these fungible tokens `VATIC` for a validator `A`. As soon as a user delegates to a validator `A`, they will be issued `VATIC` based on an exchange rate of `MATIC/VATIC` pair. As users accrue value the exchange rate indicates that they can now withdraw more `MATIC` for each `VATIC` and when users get slashed, users withdraw less `MATIC` for their `VATIC`.

Note that `MATIC` is a staking token. A delegator needs to have `MATIC` tokens to participate in the delegation.

Initially, a delegator `D` buys tokens from validator `A` specific pool when `1 MATIC per 1 VATIC`.

When a validator gets rewarded with more `MATIC` tokens, new tokens are added to the pool. Let's say with the current pool of `100 MATIC` tokens, `10 MATIC` rewards are added to the pool. But since the total supply of `VATIC` tokens didn't change due to rewards, the exchange rate becomes `1 MATIC per 0.9 VATIC`. Now, delegator `D` gets more `MATIC` for the same shares.

`VATIC`: Validator specific minted validator share tokens (ERC20 tokens)

## Technical specification

```solidity
uint256 public validatorId; // Delegation contract for validator
uint256 public validatorRewards; // accumulated rewards for validator
uint256 public commissionRate; // validator's cut %
uint256 public validatorDelegatorRatio = 10; // to be implemented/used
uint256 public totalStake;
uint256 public rewards; // rewards for pool of delegation stake
uint256 public activeAmount; // # of tokens delegated which are part of active stake
```

Exchange rate is calculated as below:

```js
ExchangeRate = (totalDelegatedPower + delegatorRewardPool) / totalDelegatorShares
```

## Methods and variables

### buyVoucher

```js
function buyVoucher(uint256 _amount) public;
```

- Transfer the `_amount` to stakeManager and update the timeline data structure for active stake.
- `updateValidatorState` is used to update timeline DS.
- `Mint` delegation shares using current `exchangeRate` for `_amount`.
- `amountStaked` is used to keep track of active stake of each delegator in order to calculate liquid rewards.

### sellVoucher

```js
function sellVoucher() public;
```

- Using current `exchangeRate` and number of shares to calculate total amount (active stake + rewards).
- `unBond` active stake from validator and transfer rewards to delegator, if any.
- Must remove active stake from timeline using `updateValidatorState` in stakeManger.
- `delegators` mapping is used to keep track of stake in withdrawal period.

### withdrawRewards

```js
function withdrawRewards() public;
```

- For a delegator, calculate the rewards and transfer, and depending upon `exchangeRate` burn count of shares.
- Example: if a delegator owns 100 shares and exchange rate is 200 so rewards are 100 tokens, transfer 100 tokens to delegator. Remaining stake is 100 so using exchange rate 200, now it is worth 50 shares. So burn 50 shares. Delegator now has 50 shares worth 100 tokens (which he initially staked / delegated).

### reStake

Restake can work in two ways: delegator can buy more shares using `buyVoucher` or reStake rewards.

```js
function reStake() public;
```

Above function is used to reStake rewards. The number of shares aren’t affected because `exchangeRate` is the same; so just the rewards are moved into active stake for both validator share contract and stakeManager timeline.

`getLiquidRewards` is used for calculating accumulated rewards i.e., delegator owns 100 share and exchange rate is 200, so rewards are 100 tokens. Move 100 tokens into active stake, since exchange rate is still same number of share will also remain same. Only difference is that now 200 tokens are considered into active stake and can't be withdrawn immediately (not a part of liquid rewards).

Purpose of reStaking is that since delegator's validator has now more active stake and they will earn more rewards for that so will the delegator.

### unStakeClaimTokens

```js
function unStakeClaimTokens()
```

Once withdrawal period is over, delegators who've sold their shares can claim their MATIC tokens. Must transfer tokens to user.

### updateCommissionRate

```js
function updateCommissionRate(uint256 newCommissionRate)
external
onlyValidator
```

- Updates commission % for the validator.

### updateRewards

```js
function updateRewards(uint256 reward, uint256 checkpointStakePower, uint256 validatorStake)
external
onlyOwner
returns (uint256)
```

When a validator gets rewards for submitting checkpoint, this function is called for disbursements of rewards between validator and delegators.
Loading

0 comments on commit 299f7cc

Please sign in to comment.