This repository contains the smart contract suite used in Polygon's POS v3 blockchain.
Note: You do not need to clone this repo in order to interact with Polygon POS v3.
- The epoch increases at the begining of the last block of an epoch, which results in the following:
- If a user changes its stake (or delegation) in the last block of an epoch X, the change will be applied on its voting power (or valdiator status) at epoch X + 2, because actually he made the balance change in epoch x + 1
There are a number of different contracts with different roles in the suite, as such an architecture diagram of the contents of contracts/
should be useful in understanding where to find what you're looking for:
│ child/ "contracts that live on the child chain (POS v3)"
├─ ChildValidatorSet - "staking, delegating, committing epochs, reward distribution"
├─ StateReceiver — "child chain component of a message bridge"
├─ System - "various infra/precompile addresses on the child chain"
│ common/ "libraries used on both the child and root chains"
├─ BLS - "BLS signature operations"
├─ BN256G2 - "elliptic curve operations on G2 for BN256 (used for BLS)"
├─ Merkle - "checks membership of a hash in a merkle tree"
│ interfaces/ "interfaces for all contracts"
│ libs/ "libraries used for specific applications"
├─ ModExp — "modular exponentiation (from Hubble Project, for BLS)"
├─ ValidatorQueue - "lib of operations for the validator queue"
├─ ValidatorStorage — "statistical red-black tree lib for ordering validators"
├─ WithdrawalQueue — "lib of operations for the rewards withdrawal queue"
│ mocks/ "mocks of various contracts for testing"
│ root/ "contracts that live on the root chain (Ethereum mainnet)"
├─ CheckpointManager - "receives and executes messages from child"
├─ RootValidatorSet - "*LIKELY TO CHANGE* stores data from child about validators and epochs"
├─ StateSender - "sends messages to child"
This repo is a hybrid Hardhat and Foundry environment. There are a number of add-ons, some of which we will detail here. Unlike standard Foundry environments, the contracts are located in contracts/
(as opposed to src/
) in order to conform with the general Hardhat project architecture. The Foundry/Solidity tests live in test/forge/
whereas the Hardhat/Typescript tests are at the root level of test/
. (For more details on the tests, see Running Tests in the Using This Repo section.)
The following is a brief overview of some of the files and directories in the project root:
│ .github/workflows/ - "CI (Github Actions) script: formats, lints, runs tests, coverage, Slither"
│ contracts/ - "all smart contracts, including mocks, but excluding Foundry tests and libs"
│ docs/ - "smart contract docs autogenerated from natspec"
│ lib/ - "smart contract libraries utilized by Foundry"
│ scripts/ - "Hardhat scripts, currently not updated, may contain deployment scripts in the future"
│ test/ - "both HH/TS and Foundry/Sol tests"
│ ts/ - "Typescript libraries for BLS/Elliptic Curves for testing BLS/BN256G2"
│ types/ - "Typescript types"
│ .env.example - "example env var file for using the HH env to connect with public nets/testnets"
│ .eslint.js - "JavaScript/TypeScript linter settings"
│ .nvmrc - "recommended Node version using nvm"
│ .prettierrc - "code formatting settings"
│ .solcover.js - "solidity-coverage settings"
│ .solhint.json - "Solidity linter settings"
│ foundry.toml - "Foundry configuration file"
│ hardhat.config.ts - "Hardhat configuration file"
│ slither.config.json - "settings for the Slither static analyzer"
The package-lock.json
is also provided to ensure the ability to install the same versions of the npm packages used in development and testing.
In order to work with this repo locally, you will need Node (preferably using nvm) in order to work with the Hardhat part of the repo.
In addition, to work with Foundry, you will need to have it installed. The recommended method is to use their foundryup
tool, which can be installed (and automatically install Foundry) using this command:
curl -L https://foundry.paradigm.xyz | bash
Note that this only works on Linux and Mac. For Windows, or if foundryup
doesn't work, consult their documentation.
This repo is a hybrid Hardhat and Foundry environment. There are a number of add-ons, some of which we will detail here. Unlike standard Foundry environments, the contracts are located in contracts/
(as opposed to src/
) in order to conform with the general Hardhat project architecture. The Foundry/Solidity tests live in test/forge/
whereas the Hardhat/Typescript tests are at the root level of test/
. (For more details on the tests, see Running Tests in the Using This Repo section.)
Install Foundry libs:
In addition, to work with Foundry, you will need to have it installed. The recommended method is to use their foundryup
tool, which can be installed (and automatically install Foundry) using this command:
curl -L https://foundry.paradigm.xyz | bash
Note that this only works on Linux and Mac. For Windows, or if foundryup
doesn't work, consult their documentation.
You do not need to clone this repo in order to interact with the Polygon core contracts
If you would like to work with these contracts in a development environment, first clone the repo:
git clone [email protected]:maticnetwork/v3-contracts.git
If you have nvm installed (recommended), you can run nvm use #
to set your version of Node to the same as used in development and testing.
Install JS/TS (Hardhat) dependencies:
npm i
Install Foundry libs:
forge install
There are a few things that should be done to set up the repo once you've cloned it and installed the dependencies and libraries. An important step for various parts of the repo to work properly is to set up a .env
file. There is an .example.env
file provided, copy it and rename the copy .env
.
The v3 contract set is meant to be deployed across two blockchains, which are called the root chain and child chain. In the case of Polygon POS v3 itself, Ethereum mainnet is the root chain, while Polygon POS v3 is the child chain. In order to give users the ability to work with these contracts on the chains of their choice, four networks are configured in Hardhat: root
, rootTest
, child
, and childTest
. To interact with whichever networks you would like to use as root and/or child, you will need to add a URL pointing to an RPC endpoint on the relevant chain in your .env
file. This can be a RPC provider such as Ankr or Alchemy, in which case you would put the entire URL including the API key into the relevant line of the .env
, or could be a local node, in which case you would put https://localhost:<PORT_NUMBER>
(usually 8545).
A field for a private key is also provided in the .env
. You will need to input this if you are interacting with any public networks (for example, deploying the contracts to a testnet).
Lastly, there are fields for an Etherscan and Polygonscan for verifying any deployed contracts on the Ethereum or Polygon mainnets or testnets. (Some additional configuration may be required, only Eth mainnet, Goerli, Polygon POS v1, and Mumbai are configured as of this writing.)
Hardhat:
npx hardhat compile --show-stack-traces
hardhat-ts
automatically generates typings for you after compilation, to use in tests and scripts. You can import them like: import { ... } from "../typechain-types";
Similarly, the hardhat-dodoc
package autogenerates smart contract documentation in docs/
every time Hardhat compiles the contract. If you wish to disable this, uncomment the runOnCompile: false
line in the dodoc
object in hardhat.config.ts
.
Foundry:
forge build
As mentioned previously, there are two separate test suites, one in Hardhat/Typescript, and the other in Foundry/Solidity. The HH tests are structured more as scenario tests, generally running through an entire interaction or process, while the Foundry tests are structured more as unit tests. This is coincidental, and is not a set rule.
Hardhat:
npx hardhat test
The Hardhat tests have gas reporting enabled by default, you can disable them from hardhat.config.ts
by setting enabled
in the gasReporter
object in hardhat.config.ts
or by setting REPORT_GAS
to false
in the .env
.
Foundry:
forge test
Simple gas profiling is included in Foundry tests by default. For a more complete gas profile using Foundry, see their documentation.
Simple gas profiling is included in Foundry tests by default. For a more complete gas profile using Foundry, see their documentation.
The linters run from inside the Hardhat/JS environment.
npm run lint # runs all linters at once
npm run lint:sol # only runs solhint and prettier
npm run lint:ts # only runs prettier and eslint
We do not know of a way to see the general coverage from the TS and Solidity tests combined at this juncture. Instead, the coverage of each suite can be checked individually.
Hardhat:
npx hardhat coverage
# or
npm run coverage
Foundry:
forge coverage
First, install slither by following the instructions here. Then, run:
slither .
# or
npm run slither
There is a CI script for Github Actions in .github/workflows/
. Currently it runs:
- linters
- both test suites (fails if any tests fail)
- coverage report (currently only HH)
- Slither
This repo makes use of Dodoc, a Hardhat plugin from Primitive Finance which generates Markdown docs on contracts from their natspec. The docs are generated on every compile, and can be found in the docs/
directory.