Skip to content

Commit 50cebfe

Browse files
committed
Improve deployment process
1 parent fd15ce8 commit 50cebfe

File tree

10 files changed

+962
-547
lines changed

10 files changed

+962
-547
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ cache/
55
artifacts/
66
.env
77
coverage/
8-
coverage.json
8+
coverage.json
9+
deployments/
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// SPDX-License-Identifier: GPL-3.0-only
2+
pragma solidity 0.8.18;
3+
4+
import {RocketStorageInterface} from "../../interface/RocketStorageInterface.sol";
5+
6+
/// @dev NOT USED IN PRODUCTION - Helper contract used to perform manual edits to storage
7+
contract StorageHelper {
8+
9+
RocketStorageInterface immutable public rocketStorage;
10+
11+
modifier onlyGuardian() {
12+
require(msg.sender == rocketStorage.getGuardian(), "Account is not a temporary guardian");
13+
_;
14+
}
15+
16+
// Construct
17+
constructor(RocketStorageInterface _rocketStorageAddress) {
18+
rocketStorage = _rocketStorageAddress;
19+
}
20+
21+
function getAddress(bytes32 _key) external view returns (address) {
22+
return rocketStorage.getAddress(_key);
23+
}
24+
25+
function getUint(bytes32 _key) external view returns (uint) {
26+
return rocketStorage.getUint(_key);
27+
}
28+
29+
function getString(bytes32 _key) external view returns (string memory) {
30+
return rocketStorage.getString(_key);
31+
}
32+
33+
function getBytes(bytes32 _key) external view returns (bytes memory) {
34+
return rocketStorage.getBytes(_key);
35+
}
36+
37+
function getBool(bytes32 _key) external view returns (bool) {
38+
return rocketStorage.getBool(_key);
39+
}
40+
41+
function getInt(bytes32 _key) external view returns (int) {
42+
return rocketStorage.getInt(_key);
43+
}
44+
45+
function getBytes32(bytes32 _key) external view returns (bytes32) {
46+
return rocketStorage.getBytes32(_key);
47+
}
48+
49+
function setAddress(bytes32 _key, address _value) external onlyGuardian {
50+
rocketStorage.setAddress(_key, _value);
51+
}
52+
53+
function setUint(bytes32 _key, uint _value) external onlyGuardian {
54+
rocketStorage.setUint(_key, _value);
55+
}
56+
57+
function setString(bytes32 _key, string memory _value) external onlyGuardian {
58+
rocketStorage.setString(_key, _value);
59+
}
60+
61+
function setBytes(bytes32 _key, bytes memory _value) external onlyGuardian {
62+
rocketStorage.setBytes(_key, _value);
63+
}
64+
65+
function setBool(bytes32 _key, bool _value) external onlyGuardian {
66+
rocketStorage.setBool(_key, _value);
67+
}
68+
69+
function setInt(bytes32 _key, int _value) external onlyGuardian {
70+
rocketStorage.setInt(_key, _value);
71+
}
72+
73+
function setBytes32(bytes32 _key, bytes32 _value) external onlyGuardian {
74+
rocketStorage.setBytes32(_key, _value);
75+
}
76+
77+
/// @dev Storage delete methods
78+
function deleteAddress(bytes32 _key) external onlyGuardian {
79+
rocketStorage.deleteAddress(_key);
80+
}
81+
82+
function deleteUint(bytes32 _key) external onlyGuardian {
83+
rocketStorage.deleteUint(_key);
84+
}
85+
86+
function deleteString(bytes32 _key) external onlyGuardian {
87+
rocketStorage.deleteString(_key);
88+
}
89+
90+
function deleteBytes(bytes32 _key) external onlyGuardian {
91+
rocketStorage.deleteBytes(_key);
92+
}
93+
94+
function deleteBool(bytes32 _key) external onlyGuardian {
95+
rocketStorage.deleteBool(_key);
96+
}
97+
98+
function deleteInt(bytes32 _key) external onlyGuardian {
99+
rocketStorage.deleteInt(_key);
100+
}
101+
102+
function deleteBytes32(bytes32 _key) external onlyGuardian {
103+
rocketStorage.deleteBytes32(_key);
104+
}
105+
106+
function addUint(bytes32 _key, uint256 _amount) external onlyGuardian {
107+
rocketStorage.addUint(_key, _amount);
108+
}
109+
110+
function subUint(bytes32 _key, uint256 _amount) external onlyGuardian {
111+
rocketStorage.subUint(_key, _amount);
112+
}
113+
}

hardhat.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ module.exports = Object.assign(common, {
2121
port: 8545,
2222
network_id: '*',
2323
},
24-
testnet: {
24+
custom: {
2525
url: `${providerUrl}`,
2626
accounts: {
2727
mnemonic: mnemonicPhrase,

scripts/deploy.js

Lines changed: 169 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,170 @@
1-
import { deployRocketPool } from '../test/_helpers/deployment';
1+
import { RocketPoolDeployer } from '../test/_helpers/deployer';
2+
import { artifacts } from '../test/_utils/artifacts';
3+
import { injectBNHelpers } from '../test/_helpers/bn';
4+
import { EtherscanVerifier } from '../test/_helpers/verify';
5+
import fs from 'fs';
6+
import path from 'path';
7+
8+
const hre = require('hardhat');
9+
const ethers = hre.ethers;
10+
11+
const chain = process.env.CHAIN || 'mainnet';
12+
const verify = process.env.VERIFY === 'true' || false;
13+
const preamble = process.env.PREAMBLE || null;
14+
const etherscanApiKey = process.env.ETHERSCAN_API_KEY || null;
15+
16+
const chainOpts = {
17+
'mainnet': {
18+
deployer: {
19+
depositAddress: '0x00000000219ab540356cBB839Cbe05303d7705Fa',
20+
rocketTokenRPLFixedSupply: '0xb4efd85c19999d84251304bda99e90b92300bd93',
21+
},
22+
deployStorageHelper: false,
23+
mintDRPL: false,
24+
setDefaults: false,
25+
},
26+
'hoodi': {
27+
deployer: {
28+
depositAddress: '0x00000000219ab540356cBB839Cbe05303d7705Fa',
29+
rocketTokenRPLFixedSupply: null,
30+
},
31+
deployStorageHelper: true,
32+
mintDRPL: true,
33+
setDefaults: true,
34+
},
35+
};
36+
37+
injectBNHelpers();
38+
39+
async function deploy() {
40+
const opts = chainOpts[chain];
41+
const [signer] = await ethers.getSigners();
42+
const deployer = new RocketPoolDeployer(signer, opts.deployer);
43+
44+
// Add storageHelper to deployment plan
45+
if (opts.deployStorageHelper) {
46+
deployer.contractPlan['storageHelper'] = {
47+
constructorArgs: () => deployer.defaultConstructorArgs(),
48+
artifact: artifacts.require('StorageHelper'),
49+
};
50+
}
51+
52+
// Bootstrap default parameters
53+
if (opts.setDefaults) {
54+
deployer.addStage('Set default parameters', 110, [
55+
async () => {
56+
await deployer.bootstrapProtocolDAOSetting('rocketDAOProtocolSettingsDeposit', 'deposit.enabled', true);
57+
await deployer.bootstrapProtocolDAOSetting('rocketDAOProtocolSettingsDeposit', 'deposit.assign.enabled', true);
58+
await deployer.bootstrapProtocolDAOSetting('rocketDAOProtocolSettingsDeposit', 'deposit.pool.maximum', '1000'.ether);
59+
await deployer.bootstrapProtocolDAOSetting('rocketDAOProtocolSettingsNode', 'node.registration.enabled', true);
60+
await deployer.bootstrapProtocolDAOSetting('rocketDAOProtocolSettingsNode', 'node.deposit.enabled', true);
61+
await deployer.bootstrapProtocolDAOSetting('rocketDAOProtocolSettingsNode', 'node.vacant.minipools.enabled', true);
62+
await deployer.bootstrapProtocolDAOSetting('rocketDAOProtocolSettingsMinipool', 'minipool.submit.withdrawable.enabled', true);
63+
await deployer.bootstrapProtocolDAOSetting('rocketDAOProtocolSettingsMinipool', 'minipool.bond.reduction.enabled', true);
64+
await deployer.bootstrapProtocolDAOSetting('rocketDAOProtocolSettingsNetwork', 'network.node.fee.minimum', '0.05'.ether);
65+
await deployer.bootstrapProtocolDAOSetting('rocketDAOProtocolSettingsNetwork', 'network.node.fee.target', '0.1'.ether);
66+
await deployer.bootstrapProtocolDAOSetting('rocketDAOProtocolSettingsNetwork', 'network.node.fee.maximum', '0.2'.ether);
67+
await deployer.bootstrapProtocolDAOSetting('rocketDAOProtocolSettingsNetwork', 'network.node.demand.range', '1000'.ether);
68+
await deployer.bootstrapProtocolDAOSetting('rocketDAOProtocolSettingsInflation', 'rpl.inflation.interval.start', Math.floor(new Date().getTime() / 1000) + (60 * 60 * 24 * 14));
69+
await deployer.bootstrapProtocolDAOClaimers('0.275'.ether, '0.025'.ether, '0.7'.ether);
70+
},
71+
]);
72+
}
73+
74+
// Mint the total DRPL supply to the deployer
75+
if (opts.mintDRPL) {
76+
deployer.addStage('Mint DRPL supply', 120, [
77+
async () => {
78+
const rocketTokenRPLFixedSupply = deployer.deployedContracts['rocketTokenRPLFixedSupply'].instance;
79+
const totalSupplyCap = await rocketTokenRPLFixedSupply.totalSupplyCap();
80+
deployer.log(`- Minting ${ethers.formatEther(totalSupplyCap)} DRPL to ${signer.address}`, 'white');
81+
await rocketTokenRPLFixedSupply.mint(signer.address, totalSupplyCap);
82+
},
83+
]);
84+
}
85+
86+
const balance = await ethers.provider.getBalance(signer.address);
87+
console.log(`Chain: ${chain}`);
88+
console.log(`Deployer: ${signer.address}`);
89+
console.log(`Deployer Balance: ${ethers.formatEther(balance)} ETH`);
90+
console.log('\n');
91+
92+
// Perform deployment
93+
const contracts = await deployer.deploy();
94+
95+
// Compile deployment information for saving
96+
const deploymentData = {
97+
deployer: signer.address,
98+
chain: chain,
99+
verification: [],
100+
addresses: {},
101+
buildInfos: {},
102+
};
103+
104+
// Compile set of build infos
105+
const buildInfoMap = {};
106+
for (const contract in contracts) {
107+
const artifact = contracts[contract].artifact;
108+
const buildInfo = hre.artifacts.getBuildInfoSync(`${artifact.sourceName}:${artifact.contractName}`);
109+
deploymentData.buildInfos[buildInfo.id] = buildInfo;
110+
buildInfoMap[contract] = buildInfo.id;
111+
}
112+
113+
// Compile list of information needed for verification
114+
for (const contract in contracts) {
115+
const artifact = contracts[contract].artifact;
116+
deploymentData.verification.push({
117+
sourceName: artifact.sourceName,
118+
contractName: artifact.contractName,
119+
address: contracts[contract].address,
120+
constructorArgs: contracts[contract].constructorArgs,
121+
buildInfoId: buildInfoMap[contract],
122+
});
123+
deploymentData.addresses[artifact.contractName] = contracts[contract].address;
124+
}
125+
126+
// Save deployment data
127+
const deployFile = 'deployments' + path.sep + chain + '_' + (new Date().toISOString()) + '.json';
128+
if (!fs.existsSync('deployments')) {
129+
fs.mkdirSync('deployments');
130+
}
131+
const jsonDeploymentData = JSON.stringify(deploymentData, null, 2);
132+
fs.writeFileSync(deployFile, jsonDeploymentData, 'utf8');
133+
fs.writeFileSync('deployments' + path.sep + 'latest.json', jsonDeploymentData, 'utf8');
134+
135+
console.log('Deployment data saved to `' + deployFile + '`');
136+
console.log();
137+
138+
// Optionally start verification process
139+
if (verify) {
140+
// Verify all deployed contracts
141+
const verifierOpts = {
142+
chain: chain,
143+
preamble: preamble !== null ? fs.readFileSync(process.cwd() + path.sep + preamble, 'utf8') : '',
144+
apiKey: etherscanApiKey,
145+
};
146+
const verifier = new EtherscanVerifier(deploymentData.buildInfos, verifierOpts);
147+
const verificationResults = await verifier.verifyAll(deploymentData.verification);
148+
149+
console.log();
150+
console.log('# Verification results')
151+
console.log();
152+
153+
for (const contract in verificationResults) {
154+
const guid = verificationResults[contract];
155+
if (guid === null) {
156+
console.log(` - ${contract}: Failed to submit`);
157+
} else {
158+
const status = await verifier.getVerificationStatus(verificationResults[contract]);
159+
console.log(` - ${contract}: ${status.result}`);
160+
}
161+
}
162+
163+
console.log();
164+
}
165+
166+
console.log('# Deployment complete');
167+
}
168+
169+
deploy().then(() => process.exit());
2170

3-
deployRocketPool().then(function() {
4-
process.exit(0);
5-
});

0 commit comments

Comments
 (0)