Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions packages/contracts/deploy/00_info/01_info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getProductionNetworkName,
isLocal,
} from '../../utils/helpers';
import {forkNetwork} from '../helpers';
import {getNetworkByNameOrAlias} from '@aragon/osx-commons-configs';
import {UnsupportedNetworkError} from '@aragon/osx-commons-sdk';
import {DeployFunction} from 'hardhat-deploy/types';
Expand All @@ -20,7 +21,9 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
console.log(`\n✨ ${path.basename(__filename)}:`);

const [deployer] = await hre.ethers.getSigners();
if (isLocal(hre)) {
if (process.env.FORKING_RPC_URL) {
await forkNetwork(hre, process.env.FORKING_RPC_URL);
} else if (isLocal(hre)) {
const productionNetworkName: string = getProductionNetworkName(hre);

console.log(
Expand All @@ -32,16 +35,11 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
if (networkConfig === null) {
throw new UnsupportedNetworkError(productionNetworkName);
}
await hre.network.provider.request({
method: 'hardhat_reset',
params: [
{
forking: {
jsonRpcUrl: networkConfig.url,
},
},
],
});
if (!networkConfig.url) {
throw new Error('RPC Url on network not defined');
}

await forkNetwork(hre, networkConfig.url);
} else {
console.log(`Production deployment on network '${hre.network.name}'.`);
}
Expand Down
118 changes: 95 additions & 23 deletions packages/contracts/deploy/10_create_repo/11_create_repo.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import {PLUGIN_REPO_ENS_SUBDOMAIN_NAME} from '../../plugin-settings';
import {
PLUGIN_REPO_ENS_SUBDOMAIN_NAME,
PLUGIN_CONTRACT_NAME,
} from '../../plugin-settings';
import {
findPluginRepo,
getProductionNetworkName,
pluginEnsDomain,
isValidAddress,
} from '../../utils/helpers';
import {saveToDeployedJson} from '../helpers';
import {
getLatestNetworkDeployment,
getNetworkNameByAlias,
Expand All @@ -18,6 +23,7 @@ import {
PluginRepo__factory,
PluginRepoFactory__factory,
} from '@aragon/osx-ethers';
import {ethers} from 'hardhat';
import {DeployFunction} from 'hardhat-deploy/types';
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import path from 'path';
Expand All @@ -27,6 +33,7 @@ import path from 'path';
* @param {HardhatRuntimeEnvironment} hre
*/
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
// todo change this log
console.log(
`Creating the '${pluginEnsDomain(
hre
Expand All @@ -35,24 +42,57 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {

const [deployer] = await hre.ethers.getSigners();

// Get the Aragon `PluginRepoFactory` from the `osx-commons-configs`
const productionNetworkName = getProductionNetworkName(hre);
const network = getNetworkNameByAlias(productionNetworkName);
if (network === null) {
throw new UnsupportedNetworkError(productionNetworkName);
}
const networkDeployments = getLatestNetworkDeployment(network);
if (networkDeployments === null) {
throw `Deployments are not available on network ${network}.`;
let pluginRepoFactoryAddress = process.env.PLUGIN_REPO_FACTORY_ADDRESS;
let subdomainRegistrar;

if (pluginRepoFactoryAddress) {
if (!isValidAddress(pluginRepoFactoryAddress)) {
throw new Error('Plugin Repo Factory in .env is not of type Address');
}
// use this factory
const pluginRepoFactory = PluginRepoFactory__factory.connect(
pluginRepoFactoryAddress,
deployer
);

const pluginRepoRegistry = PluginRepoRegistry__factory.connect(
await pluginRepoFactory.pluginRepoRegistry(),
deployer
);
subdomainRegistrar = await pluginRepoRegistry.subdomainRegistrar();
} else {
// get the factory from osx-commons-configs deployments

// Get the Aragon `PluginRepoFactory` from the `osx-commons-configs`
const productionNetworkName = getProductionNetworkName(hre);
const network = getNetworkNameByAlias(productionNetworkName);
if (network === null) {
throw new UnsupportedNetworkError(productionNetworkName);
}
const networkDeployments = getLatestNetworkDeployment(network);
if (networkDeployments === null) {
throw `Deployments are not available on network ${network}.`;
}

pluginRepoFactoryAddress = networkDeployments.PluginRepoFactory.address;

subdomainRegistrar =
networkDeployments.PluginENSSubdomainRegistrarProxy.address;
}
// subdomain will depend on if the framework has the ens or not
const subdomain =
subdomainRegistrar !== ethers.constants.AddressZero
? PLUGIN_REPO_ENS_SUBDOMAIN_NAME
: '';

const pluginRepoFactory = PluginRepoFactory__factory.connect(
networkDeployments.PluginRepoFactory.address,
pluginRepoFactoryAddress,
deployer
);

// Create the `PluginRepo` through the Aragon `PluginRepoFactory`
const tx = await pluginRepoFactory.createPluginRepo(
PLUGIN_REPO_ENS_SUBDOMAIN_NAME,
subdomain,
deployer.address
);

Expand All @@ -70,13 +110,35 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
);

console.log(
`PluginRepo '${pluginEnsDomain(hre)}' deployed at '${pluginRepo.address}'.`
`PluginRepo ${
subdomainRegistrar !== ethers.constants.AddressZero
? 'with ens:' + pluginEnsDomain(hre)
: 'without ens'
} deployed at '${pluginRepo.address}'.`
);

hre.aragonToVerifyContracts.push({
address: pluginRepo.address,
args: [],
});

saveToDeployedJson(
[
{
name: PLUGIN_CONTRACT_NAME + 'RepoProxy',
address: pluginRepo.address,
blockNumber: tx.blockNumber,
txHash: tx.hash,
},
{
name: PLUGIN_CONTRACT_NAME + 'RepoImplementation',
address: await pluginRepoFactory.pluginRepoBase(),
blockNumber: null,
txHash: null,
},
],
true
);
};

export default func;
Expand All @@ -89,24 +151,34 @@ func.tags = ['CreateRepo'];
func.skip = async (hre: HardhatRuntimeEnvironment) => {
console.log(`\n🏗️ ${path.basename(__filename)}:`);

// Check if the ens record exists already
const {pluginRepo, ensDomain} = await findPluginRepo(hre);
// try getting the plugin repo.
const res = await findPluginRepo(hre);
const pluginRepoAddress = res.pluginRepo?.address;
const ensDomain = res.ensDomain;

if (pluginRepo !== null) {
console.log(
`ENS name '${ensDomain}' was claimed already at '${
pluginRepo.address
}' on network '${getProductionNetworkName(hre)}'. Skipping deployment...`
);
if (pluginRepoAddress) {
if (ensDomain != '') {
console.log(
`ENS name '${ensDomain}' was claimed already at '${pluginRepoAddress}' on network '${getProductionNetworkName(
hre
)}'. Skipping deployment...`
);
} else {
console.log(
`Plugin Repo already deployed at '${pluginRepoAddress}' on network '${getProductionNetworkName(
hre
)}'. Skipping deployment...`
);
}

hre.aragonToVerifyContracts.push({
address: pluginRepo.address,
address: pluginRepoAddress,
args: [],
});

return true;
} else {
console.log(`ENS name '${ensDomain}' is unclaimed. Deploying...`);
console.log('Deploying Plugin Repo');

return false;
}
Expand Down
97 changes: 75 additions & 22 deletions packages/contracts/deploy/20_new_version/23_publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,37 @@ import {
impersonatedManagementDaoSigner,
isLocal,
pluginEnsDomain,
isValidAddress,
} from '../../utils/helpers';
import {getLatestContractAddress} from '../helpers';
import {PLUGIN_REPO_PERMISSIONS, uploadToPinata} from '@aragon/osx-commons-sdk';
import {PluginRepo} from '@aragon/osx-ethers';
import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers';
import {writeFile} from 'fs/promises';
import {ethers} from 'hardhat';
import {DeployFunction} from 'hardhat-deploy/types';
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import path from 'path';

async function createVersion(
pluginRepo: PluginRepo,
release: number,
setup: string,
releaseMetadataURI: string,
buildMetadataURI: string,
signer: SignerWithAddress
) {
const tx = await pluginRepo
.connect(signer)
.createVersion(
release,
setup,
ethers.utils.hexlify(ethers.utils.toUtf8Bytes(buildMetadataURI)),
ethers.utils.hexlify(ethers.utils.toUtf8Bytes(releaseMetadataURI))
);
await tx.wait();
}

/**
* Publishes the plugin setup in the plugin repo as a new version as specified in the `./plugin-settings.ts` file.
* @param {HardhatRuntimeEnvironment} hre
Expand Down Expand Up @@ -56,7 +79,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
// Get PluginRepo
const {pluginRepo, ensDomain} = await findPluginRepo(hre);
if (pluginRepo === null) {
throw `PluginRepo '${ensDomain}' does not exist yet.`;
throw `Can't find Plugin Repo...`;
}

// Check release number
Expand All @@ -73,18 +96,24 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
// Check build number
const latestBuild = (await pluginRepo.buildCount(VERSION.release)).toNumber();

if (VERSION.build < latestBuild) {
throw Error(
`Publishing with build number ${VERSION.build} is not possible. The latest build is ${latestBuild}. Aborting publication...`
);
}
if (VERSION.build > latestBuild + 1) {
throw Error(
`Publishing with build number ${VERSION.build} is not possible.
if (latestBuild == 0 && VERSION.build > 1) {
// it means there's no build yet on the repo on the specific VERSION.release
// and build version in the plugin settings is > 1, meaning that
// it must push placeholder contracts and as the last one, push the actual plugin setup.
} else {
if (VERSION.build < latestBuild) {
throw Error(
`Publishing with build number ${VERSION.build} is not possible. The latest build is ${latestBuild}. Aborting publication...`
);
}
if (VERSION.build > latestBuild + 1) {
throw Error(
`Publishing with build number ${VERSION.build} is not possible.
The latest build is ${latestBuild} and the next release you can publish is release number ${
latestBuild + 1
}. Aborting publication...`
);
latestBuild + 1
}. Aborting publication...`
);
}
}

if (setup == undefined || setup?.receipt == undefined) {
Expand Down Expand Up @@ -114,17 +143,41 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
[]
)
) {
// Create the new version
const tx = await pluginRepo
.connect(signer)
.createVersion(
VERSION.release,
setup.address,
ethers.utils.hexlify(ethers.utils.toUtf8Bytes(buildMetadataURI)),
ethers.utils.hexlify(ethers.utils.toUtf8Bytes(releaseMetadataURI))
);
if (latestBuild == 0 && VERSION.build > 1) {
// We are publishing the first version as build > 1.
// So we need to publish placeholders first..
const placeholderSetup =
process.env.PLACEHOLDER_SETUP ??
getLatestContractAddress('PlaceholderSetup', hre);

if (!isValidAddress(placeholderSetup)) {
throw new Error(
'Aborting. Placeholder setup not present in this network or in .env or is not a valid address (is not an address or is address zero)'
);
}

await tx.wait();
for (let i = 0; i < VERSION.build - 1; i++) {
console.log('Publishing placeholder', i + 1);
await createVersion(
pluginRepo,
VERSION.release,
placeholderSetup,
`{}`,
'placeholder-setup-build',
signer
);
}
}

// Create the new version
await createVersion(
pluginRepo,
VERSION.release,
setup.address,
buildMetadataURI,
releaseMetadataURI,
signer
);

const version = await pluginRepo['getLatestVersion(uint8)'](
VERSION.release
Expand Down
Loading
Loading