Skip to content

Commit

Permalink
add option to deploy contracts with machine readable output (json)
Browse files Browse the repository at this point in the history
  • Loading branch information
y0sher committed Nov 3, 2024
1 parent e01edee commit f76ce4d
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 38 deletions.
29 changes: 27 additions & 2 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { NetworkUserConfig } from 'hardhat/types';

import 'dotenv/config';

import '@nomicfoundation/hardhat-toolbox-viem';
import '@nomicfoundation/hardhat-chai-matchers';
import '@openzeppelin/hardhat-upgrades';

Expand Down Expand Up @@ -54,7 +53,10 @@ const config: HardhatUserConfig = {
},
},
etherscan: {
apiKey: process.env.ETHERSCAN_KEY,
apiKey: {
'holesky': process.env.ETHERSCAN_KEY,
'devnet': 'x',
},
customChains: [
{
network: 'holesky',
Expand All @@ -64,6 +66,14 @@ const config: HardhatUserConfig = {
browserURL: 'https://holesky.etherscan.io',
},
},
{
network: 'devnet',
chainId: 3151908,
urls: {
apiURL: `${process.env.BLOCKSCOUT_URL}/api`,
browserURL: process.env.BLOCKSCOUT_URL,
},
}
],
},
contractSizer: {
Expand All @@ -86,6 +96,7 @@ const config: HardhatUserConfig = {
},
};


if (process.env.HOLESKY_ETH_NODE_URL && process.env.HOLESKY_OWNER_PRIVATE_KEY) {
const sharedConfig = {
url: `${process.env.HOLESKY_ETH_NODE_URL}${process.env.NODE_PROVIDER_KEY}`,
Expand Down Expand Up @@ -135,4 +146,18 @@ if (process.env.FORK_TESTING_ENABLED) {
};
}

if (process.env.DEVNET_ETH_NODE_URL) {
config.networks = {
devnet: {
chainId: 3151908,
url: `${process.env.DEVNET_ETH_NODE_URL}`,
accounts: [
"39725efee3fb28614de3bacaffe4cc4bd8c436257e2c8bb887c4b5c4be45e76d",
],
gasPrice: +(process.env.GAS_PRICE || ''),
gas: +(process.env.GAS || ''),
} as NetworkUserConfig,
};
}

export default config;
116 changes: 80 additions & 36 deletions tasks/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { task, subtask, types } from 'hardhat/config';
import { SSVModules } from './config';


/**
@title Hardhat task to deploy all required contracts for SSVNetwork.
This task deploys the main SSVNetwork and SSVNetworkViews contracts, along with their associated modules.
Expand All @@ -15,30 +16,51 @@ The deployer account used will be the first one returned by ethers.getSigners().
Therefore, it should be appropriately configured in your Hardhat network configuration.
This task assumes that the SSVModules enum and deployment tasks for individual contracts have been properly defined.
*/
task('deploy:all', 'Deploy SSVNetwork, SSVNetworkViews and module contracts').setAction(async ({}, hre) => {
// Triggering compilation
await hre.run('compile');
task('deploy:all', 'Deploy SSVNetwork, SSVNetworkViews and module contracts')
.addOptionalParam('machine', 'outputs the machine readable output', false, types.boolean)
.setAction(async (args, hre) => {
if (!args.machine) {
// Triggering compilation if this is manual
await hre.run('compile');
}

const [deployer] = await ethers.getSigners();
console.log(`Deploying contracts with the account:${deployer.address}`);
if (!args.machine){
const [deployer] = await ethers.getSigners();
deployer.address = deployer.address.toLowerCase();
console.log(`Deploying contracts with the account:${deployer.address}`);
}

const ssvTokenAddress = await hre.run('deploy:mock-token');
const operatorsModAddress = await hre.run('deploy:module', { module: SSVModules[SSVModules.SSVOperators] });
const clustersModAddress = await hre.run('deploy:module', { module: SSVModules[SSVModules.SSVClusters] });
const daoModAddress = await hre.run('deploy:module', { module: SSVModules[SSVModules.SSVDAO] });
const viewsModAddress = await hre.run('deploy:module', { module: SSVModules[SSVModules.SSVViews] });
const ssvTokenAddress = await hre.run('deploy:token', { machine: args.machine });
const operatorsModAddress = await hre.run('deploy:module', { module: SSVModules[SSVModules.SSVOperators], machine: args.machine });
const clustersModAddress = await hre.run('deploy:module', { module: SSVModules[SSVModules.SSVClusters], machine: args.machine });
const daoModAddress = await hre.run('deploy:module', { module: SSVModules[SSVModules.SSVDAO], machine: args.machine });
const viewsModAddress = await hre.run('deploy:module', { module: SSVModules[SSVModules.SSVViews], machine: args.machine });

const { ssvNetworkProxyAddress: ssvNetworkAddress } = await hre.run('deploy:ssv-network', {
operatorsModAddress,
clustersModAddress,
daoModAddress,
viewsModAddress,
ssvTokenAddress,
machine: args.machine,
});

await hre.run('deploy:ssv-network-views', {
ssvNetworkAddress,
machine: args.machine,
});

if (args.machine) {
const jsonData = {
ssvTokenAddress,
operatorsModAddress,
clustersModAddress,
daoModAddress,
viewsModAddress,
ssvNetworkAddress,
}
console.log(JSON.stringify(jsonData));
}
});

/**
Expand Down Expand Up @@ -92,27 +114,35 @@ This subtask uses the "deploy:impl" subtask for the actual deployment.
*/
subtask('deploy:module', 'Deploys a new module contract')
.addParam('module', 'SSV Module', null, types.string)
.setAction(async ({ module }, hre) => {
.addOptionalParam('machine', 'outputs the machine readable output', false, types.boolean)
.setAction(async ({ module, machine }, hre) => {
const moduleValues = Object.values(SSVModules);
if (!moduleValues.includes(module)) {
throw new Error(`Invalid SSVModule: ${module}. Expected one of: ${moduleValues.join(', ')}`);
}

const moduleAddress = await hre.run('deploy:impl', { contract: module });
const moduleAddress = await hre.run('deploy:impl', { contract: module, machine: machine });
return moduleAddress;
});

task('deploy:token', 'Deploys SSV Token').setAction(async ({}, hre) => {
// Triggering compilation
await hre.run('compile');

console.log('Deploying SSV Network Token');
task('deploy:token', 'Deploys SSV Token')
.addOptionalParam('machine', 'outputs the machine readable output', false, types.boolean)
.setAction(async (args, hre) => {
if (!args.machine){
// Triggering compilation if this is manual
await hre.run('compile');
console.log('Deploying SSV Network Token');
}

const ssvTokenFactory = await ethers.getContractFactory('SSVToken');
const ssvToken = await ssvTokenFactory.deploy();
await ssvToken.deployed();
await ssvToken.waitForDeployment();

console.log(`SSV Network Token deployed to: ${ssvToken.address}`);
if (!args.machine){
console.log(`SSV Network Token deployed to: ${ssvToken.address}`);
}

return await ssvToken.getAddress()
});

/**
Expand All @@ -127,11 +157,11 @@ subtask('deploy:mock-token', 'Deploys / fetch SSV Token').setAction(async ({}, h

// Local networks, deploy mock token
// const ssvToken = await hre.viem.deployContract('SSVToken');
const ssvTokenFactory = await ethers.getContractFactory('SSVTokenMock');
const ssvToken = await ssvTokenFactory.deploy();
const ssvTokenFactory = await ethers.getContractFactory('SSVToken');
const ssvToken = await ssvTokenFactory.deployContract();
await ssvToken.waitForDeployment();

return ssvToken.address;
return await ssvToken.getAddress();
});

/**
Expand All @@ -147,17 +177,22 @@ The contract specified should be already compiled and exist in the 'artifacts' d
*/
subtask('deploy:impl', 'Deploys an implementation contract')
.addParam('contract', 'New contract implemetation', null, types.string)
.setAction(async ({ contract }, hre) => {
// Triggering compilation
await hre.run('compile');

.addOptionalParam('machine', 'outputs the machine readable output', false, types.boolean)
.setAction(async (args, hre) => {
if (!args.machine){
// Triggering compilation if this is manual
await hre.run('compile');
}
// Deploy implemetation contract
const contractFactory = await ethers.getContractFactory(contract);
const contractFactory = await ethers.getContractFactory(args.contract);
const contractImpl = await contractFactory.deploy();
await contractImpl.waitForDeployment();
console.log(`${contract} implementation deployed to: ${contractImpl.address}`);

return contractImpl.address;
if (!args.machine){
console.log(`${args.contract} implementation deployed to: ${await contractImpl.getAddress()}`);
}

return await contractImpl.getAddress();
});

/**
Expand All @@ -183,11 +218,15 @@ subtask('deploy:ssv-network', 'Deploys SSVNetwork contract')
.addPositionalParam('daoModAddress', 'DAO module address', null, types.string)
.addPositionalParam('viewsModAddress', 'Views module address', null, types.string)
.addPositionalParam('ssvTokenAddress', 'SSV Token address', null, types.string)
.setAction(async ({ operatorsModAddress, clustersModAddress, daoModAddress, viewsModAddress, ssvTokenAddress }) => {
.addOptionalParam('machine', 'outputs the machine readable output', false, types.boolean)
.setAction(async ({ operatorsModAddress, clustersModAddress, daoModAddress, viewsModAddress, ssvTokenAddress, machine }) => {
const ssvNetworkFactory = await ethers.getContractFactory('SSVNetwork');

// deploy SSVNetwork
console.log(`Deploying SSVNetwork with ssvToken ${ssvTokenAddress}`);
if (!machine){
console.log(`Deploying SSVNetwork with ssvToken ${ssvTokenAddress}`);
}

const ssvNetwork = await upgrades.deployProxy(
ssvNetworkFactory,
[
Expand All @@ -212,8 +251,10 @@ subtask('deploy:ssv-network', 'Deploys SSVNetwork contract')
const ssvNetworkProxyAddress = await ssvNetwork.getAddress();
const ssvNetworkImplAddress = await upgrades.erc1967.getImplementationAddress(ssvNetworkProxyAddress);

console.log(`SSVNetwork proxy deployed to: ${ssvNetworkProxyAddress}`);
console.log(`SSVNetwork implementation deployed to: ${ssvNetworkImplAddress}`);
if (!machine) {
console.log(`SSVNetwork proxy deployed to: ${ssvNetworkProxyAddress}`);
console.log(`SSVNetwork implementation deployed to: ${ssvNetworkImplAddress}`);
}

return { ssvNetworkProxyAddress, ssvNetworkImplAddress };
});
Expand All @@ -231,7 +272,8 @@ The 'SSVNetworkViews' contract specified should be already compiled and exist in
*/
subtask('deploy:ssv-network-views', 'Deploys SSVNetworkViews contract')
.addParam('ssvNetworkAddress', 'SSVNetwork address', null, types.string)
.setAction(async ({ ssvNetworkAddress }) => {
.addOptionalParam('machine', 'outputs the machine readable output', false, types.boolean)
.setAction(async ({ ssvNetworkAddress, machine }) => {
const ssvNetworkViewsFactory = await ethers.getContractFactory('SSVNetworkViews');

// deploy SSVNetwork
Expand All @@ -243,8 +285,10 @@ subtask('deploy:ssv-network-views', 'Deploys SSVNetworkViews contract')
const ssvNetworkViewsProxyAddress = await ssvNetworkViews.getAddress();
const ssvNetworkViewsImplAddress = await upgrades.erc1967.getImplementationAddress(ssvNetworkViewsProxyAddress);

console.log(`SSVNetworkViews proxy deployed to: ${ssvNetworkViewsProxyAddress}`);
console.log(`SSVNetworkViews implementation deployed to: ${ssvNetworkViewsImplAddress}`);
if (!machine){
console.log(`SSVNetworkViews proxy deployed to: ${ssvNetworkViewsProxyAddress}`);
console.log(`SSVNetworkViews implementation deployed to: ${ssvNetworkViewsImplAddress}`);
}

return { ssvNetworkViewsProxyAddress, ssvNetworkViewsImplAddress };
});

0 comments on commit f76ce4d

Please sign in to comment.