Skip to content

Commit de71996

Browse files
authored
Merge pull request #381 from 0xPolygon/dev
merge deployment scripts into `audit`
2 parents 94669d5 + 0eb19a9 commit de71996

38 files changed

+2011
-61
lines changed

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ This repository contains the smart contract suite used in Polygon's ecosystems.
1919
- [General Repo Layout](#general-repo-layout-1)
2020
- [Installation](#installation)
2121
- [Deployment](#deployment)
22+
- [Root contracts](#root-contracts)
2223
- [Environment Setup](#environment-setup)
2324
- [Compiling Contracts](#compiling-contracts)
2425
- [Running tests](#running-tests)
@@ -164,6 +165,31 @@ Deploying these contracts in the context of a production blockchain is out of th
164165

165166
One point that is worth emphasizing in this context is that from the perspective of launching a Supernet is understanding genesis contracts. Another is that for at least the time being, the decision has been made to proxify all genesis contracts in order to facilitate upgrades/updates without necessitating a hardfork or regenesis. All deployment scripts in `script/deployment` use OpenZeppelin's `TransparentUpgradeableProxy`.
166167

168+
#### Root contracts
169+
170+
Deployment scripts have been provided for each of the root chain contracts. (The child chain contracts are genesis contracts, and are not deployed traditionally; they are deployed by the client as a part of the genesis of the child chain.)
171+
172+
Some contracts in the Edge suite need be deployed only once on root. These contracts can deployed using the [`DeploySharedRootContracts`](script/deployment/DeploySharedRootContracts.sol) script, after [`sharedRootContractsConfig`](script/deployment/sharedRootContractsConfig.json) has been filled with appropriate values.
173+
174+
Other contracts are deployed on root once per Supernet. These contracts can deployed using the [`DeployNewRootContractSet.s.sol`](script/deployment/DeployNewRootContractSet.s.sol) script, after [`rootContractSetConfig.json`](script/deployment/rootContractSetConfig.json) has been filled with appropriate values.
175+
176+
Note that the script does not initialize `CheckpointManager`. Instead protects it to be initializable only by the `INITIALIZER` address later.
177+
178+
Not all root contracts are deployed at this point, however. There are parts of the bridge that need the addresses of various child contracts in order to be initialized. These contracts can deployed using the [`DeployRootTokenContracts.s.sol`](script/deployment/DeployRootTokenContracts.s.sol) script, after [`rootTokenContractsConfig.json`](script/deployment/rootTokenContractsConfig.json) has been filled with appropriate values.
179+
180+
Scripts are run by invoking:
181+
182+
```bash
183+
forge <SCRIPT_NAME> \
184+
--broadcast \
185+
<SIGNING_METHOD> \
186+
--rpc-url <RPC_URL> \
187+
--verify \
188+
--sig "run()"
189+
```
190+
191+
For the signing method and other options, consult [Foundry Book](https://book.getfoundry.sh/reference/forge/forge-script).
192+
167193
### Environment Setup
168194

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

contracts/root/CheckpointManager.sol

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ contract CheckpointManager is ICheckpointManager, Initializable {
2727
uint256[] public checkpointBlockNumbers;
2828
bytes32 public currentValidatorSetHash;
2929

30+
// slither-disable-next-line naming-convention
31+
address private immutable _INITIALIZER;
32+
33+
/// @notice If the contract is meant to be initialized at a later time, specifiy the address that will initialize it.
34+
/// @notice Otherwise, pass `address(0)`.
35+
constructor(address INITIALIZER) {
36+
// slither-disable-next-line missing-zero-check
37+
_INITIALIZER = INITIALIZER;
38+
}
39+
3040
/**
3141
* @notice Initialization function for CheckpointManager
3242
* @dev Contract can only be initialized once
@@ -40,11 +50,15 @@ contract CheckpointManager is ICheckpointManager, Initializable {
4050
uint256 chainId_,
4151
Validator[] calldata newValidatorSet
4252
) external initializer {
53+
if (_INITIALIZER != address(0)) require(msg.sender == _INITIALIZER);
54+
55+
// slither-disable-start events-maths
4356
chainId = chainId_;
4457
bls = newBls;
4558
bn256G2 = newBn256G2;
4659
currentValidatorSetLength = newValidatorSet.length;
4760
_setNewValidatorSet(newValidatorSet);
61+
// slither-disable-end events-maths
4862
}
4963

5064
/**

foundry.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ verbosity = 2
1111
ffi = true
1212
# comment out if you notice any weird behavior
1313
# sparse_mode = true
14+
fs_permissions = [
15+
{ access = "read", path = "script/deployment/sharedRootContractsConfig.json" },
16+
{ access = "read", path = "script/deployment/rootContractSetConfig.json" },
17+
{ access = "read", path = "script/deployment/rootTokenContractsConfig.json" }
18+
]
1419

1520
# do not use for computationally expensive tests
1621
[profile.intense.fuzz]
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity 0.8.19;
4+
5+
import "forge-std/Script.sol";
6+
7+
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
8+
9+
import "script/deployment/root/DeployStateSender.s.sol";
10+
import "script/deployment/root/DeployCheckpointManager.s.sol";
11+
import "script/deployment/root/DeployExitHelper.s.sol";
12+
import "script/deployment/root/staking/DeployCustomSupernetManager.s.sol";
13+
14+
contract DeployNewRootContractSet is
15+
StateSenderDeployer,
16+
CheckpointManagerDeployer,
17+
ExitHelperDeployer,
18+
CustomSupernetManagerDeployer
19+
{
20+
using stdJson for string;
21+
22+
function run()
23+
external
24+
returns (
25+
address proxyAdmin,
26+
address stateSender,
27+
address checkpointManagerLogic,
28+
address checkpointManagerProxy,
29+
address exitHelperLogic,
30+
address exitHelperProxy,
31+
address customSupernetManagerLogic,
32+
address customSupernetManagerProxy
33+
)
34+
{
35+
string memory config = vm.readFile("script/deployment/newRootContractSetConfig.json");
36+
37+
vm.startBroadcast();
38+
39+
ProxyAdmin _proxyAdmin = new ProxyAdmin();
40+
_proxyAdmin.transferOwnership(config.readAddress('["common"].proxyAdminOwner'));
41+
42+
vm.stopBroadcast();
43+
44+
proxyAdmin = address(_proxyAdmin);
45+
46+
stateSender = deployStateSender();
47+
48+
// To be initialized manually later.
49+
(checkpointManagerLogic, checkpointManagerProxy) = deployCheckpointManager(
50+
proxyAdmin,
51+
config.readAddress('["CheckpointManager"].INITIALIZER')
52+
);
53+
54+
(exitHelperLogic, exitHelperProxy) = deployExitHelper(proxyAdmin, ICheckpointManager(checkpointManagerProxy));
55+
56+
(customSupernetManagerLogic, customSupernetManagerProxy) = deployCustomSupernetManager(
57+
proxyAdmin,
58+
config.readAddress('["CustomSupernetManager"].newStakeManager'),
59+
config.readAddress('["common"].newBls'),
60+
stateSender,
61+
config.readAddress('["CustomSupernetManager"].newMatic'),
62+
config.readAddress('["CustomSupernetManager"].newChildValidatorSet'),
63+
exitHelperProxy,
64+
config.readString('["CustomSupernetManager"].newDomain')
65+
);
66+
}
67+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity 0.8.19;
4+
5+
import "forge-std/Script.sol";
6+
7+
import "script/deployment/root/DeployRootERC20Predicate.s.sol";
8+
import "script/deployment/root/DeployChildMintableERC20Predicate.s.sol";
9+
import "script/deployment/root/DeployRootERC721Predicate.s.sol";
10+
import "script/deployment/root/DeployChildMintableERC721Predicate.s.sol";
11+
import "script/deployment/root/DeployRootERC1155Predicate.s.sol";
12+
import "script/deployment/root/DeployChildMintableERC1155Predicate.s.sol";
13+
14+
contract DeployRootTokenContracts is
15+
RootERC20PredicateDeployer,
16+
ChildMintableERC20PredicateDeployer,
17+
RootERC721PredicateDeployer,
18+
ChildMintableERC721PredicateDeployer,
19+
RootERC1155PredicateDeployer,
20+
ChildMintableERC1155PredicateDeployer
21+
{
22+
using stdJson for string;
23+
24+
function run()
25+
external
26+
returns (
27+
address rootERC20PredicateLogic,
28+
address rootERC20PredicateProxy,
29+
address childMintableERC20PredicateLogic,
30+
address childMintableERC20PredicateProxy,
31+
address rootERC721PredicateLogic,
32+
address rootERC721PredicateProxy,
33+
address childMintableERC721PredicateLogic,
34+
address childMintableERC721PredicateProxy,
35+
address rootERC1155PredicateLogic,
36+
address rootERC1155PredicateProxy,
37+
address childMintableERC1155PredicateLogic,
38+
address childMintableERC1155PredicateProxy
39+
)
40+
{
41+
string memory config = vm.readFile("script/deployment/rootTokenContractsConfig.json");
42+
43+
(rootERC20PredicateLogic, rootERC20PredicateProxy) = deployRootERC20Predicate(
44+
config.readAddress('["common"].proxyAdmin'),
45+
config.readAddress('["common"].stateSender'),
46+
config.readAddress('["common"].exitHelper'),
47+
config.readAddress('["RootERC20Predicate"].newChildERC20Predicate'),
48+
config.readAddress('["common"].newChildTokenTemplate'),
49+
config.readAddress('["RootERC20Predicate"].nativeTokenRootAddress')
50+
);
51+
52+
(childMintableERC20PredicateLogic, childMintableERC20PredicateProxy) = deployChildMintableERC20Predicate(
53+
config.readAddress('["common"].proxyAdmin'),
54+
config.readAddress('["common"].stateSender'),
55+
config.readAddress('["common"].exitHelper'),
56+
rootERC20PredicateProxy,
57+
config.readAddress('["common"].newChildTokenTemplate')
58+
);
59+
60+
(rootERC721PredicateLogic, rootERC721PredicateProxy) = deployRootERC721Predicate(
61+
config.readAddress('["common"].proxyAdmin'),
62+
config.readAddress('["common"].stateSender'),
63+
config.readAddress('["common"].exitHelper'),
64+
config.readAddress('["RootERC721Predicate"].newChildERC721Predicate'),
65+
config.readAddress('["common"].newChildTokenTemplate')
66+
);
67+
68+
(childMintableERC721PredicateLogic, childMintableERC721PredicateProxy) = deployChildMintableERC721Predicate(
69+
config.readAddress('["common"].proxyAdmin'),
70+
config.readAddress('["common"].stateSender'),
71+
config.readAddress('["common"].exitHelper'),
72+
rootERC721PredicateProxy,
73+
config.readAddress('["common"].newChildTokenTemplate')
74+
);
75+
76+
(rootERC1155PredicateLogic, rootERC1155PredicateProxy) = deployRootERC1155Predicate(
77+
config.readAddress('["common"].proxyAdmin'),
78+
config.readAddress('["common"].stateSender'),
79+
config.readAddress('["common"].exitHelper'),
80+
config.readAddress('["RootERC1155Predicate"].newChildERC1155Predicate'),
81+
config.readAddress('["common"].newChildTokenTemplate')
82+
);
83+
84+
(childMintableERC1155PredicateLogic, childMintableERC1155PredicateProxy) = deployChildMintableERC1155Predicate(
85+
config.readAddress('["common"].proxyAdmin'),
86+
config.readAddress('["common"].stateSender'),
87+
config.readAddress('["common"].exitHelper'),
88+
rootERC1155PredicateProxy,
89+
config.readAddress('["common"].newChildTokenTemplate')
90+
);
91+
}
92+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity 0.8.19;
4+
5+
import "forge-std/Script.sol";
6+
7+
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
8+
9+
import "script/deployment/common/DeployBLS.s.sol";
10+
import "script/deployment/common/DeployBN256G2.s.sol";
11+
import "script/deployment/root/staking/DeployStakeManager.s.sol";
12+
13+
contract DeploySharedRootContracts is BLSDeployer, BN256G2Deployer, StakeManagerDeployer {
14+
using stdJson for string;
15+
16+
function run()
17+
external
18+
returns (address proxyAdmin, address bls, address bn256G2, address stakeManagerLogic, address stakeManagerProxy)
19+
{
20+
string memory config = vm.readFile("script/deployment/sharedRootContractsConfig.json");
21+
22+
vm.startBroadcast();
23+
24+
ProxyAdmin _proxyAdmin = new ProxyAdmin();
25+
_proxyAdmin.transferOwnership(config.readAddress('["StakeManager"].proxyAdminOwner'));
26+
27+
vm.stopBroadcast();
28+
29+
proxyAdmin = address(_proxyAdmin);
30+
31+
bls = deployBLS();
32+
33+
bn256G2 = deployBN256G2();
34+
35+
(stakeManagerLogic, stakeManagerProxy) = deployStakeManager(
36+
proxyAdmin,
37+
config.readAddress('["StakeManager"].newStakingToken')
38+
);
39+
}
40+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity 0.8.19;
4+
5+
import "forge-std/Script.sol";
6+
7+
import {BLS} from "contracts/common/BLS.sol";
8+
9+
abstract contract BLSDeployer is Script {
10+
function deployBLS() internal returns (address contractAddr) {
11+
vm.broadcast();
12+
BLS bls = new BLS();
13+
14+
contractAddr = address(bls);
15+
}
16+
}
17+
18+
contract DepoyBLS is BLSDeployer {
19+
function run() external returns (address contractAddr) {
20+
return deployBLS();
21+
}
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity 0.8.19;
4+
5+
import "forge-std/Script.sol";
6+
7+
import {BN256G2} from "contracts/common/BN256G2.sol";
8+
9+
abstract contract BN256G2Deployer is Script {
10+
function deployBN256G2() internal returns (address contractAddr) {
11+
vm.broadcast();
12+
BN256G2 bn256G2 = new BN256G2();
13+
14+
contractAddr = address(bn256G2);
15+
}
16+
}
17+
18+
contract DepoyBN256G2 is BN256G2Deployer {
19+
function run() external returns (address contractAddr) {
20+
return deployBN256G2();
21+
}
22+
}

0 commit comments

Comments
 (0)