@openzeppelin/hardhat-upgrades
Version:
[](https://docs.openzeppelin.com/upgrades-plugins/hardhat-upgrades) [](https://www.npmjs.org/package/@openzeppelin/h
99 lines (85 loc) • 3.51 kB
text/typescript
import { HardhatRuntimeEnvironment } from 'hardhat/types/hre';
import type { NetworkConnection } from 'hardhat/types/network';
import type { ContractFactory } from 'ethers';
import { deploy, DeployContractOptions, DeployTransaction, EthersOrDefenderDeployment } from './utils/index.js';
import { DeployData, getDeployData } from './utils/deploy-impl.js';
import { enableDefender } from './defender/utils.js';
import {
getContractNameAndRunValidation,
inferProxyKind,
UpgradesError,
inferInitializable,
Deployment,
RemoteDeploymentId,
} from '@openzeppelin/upgrades-core';
import { getContractInstance } from './utils/contract-instance.js';
import { ContractTypeOfFactory } from './type-extensions.js';
export interface DeployContractFunction {
<F extends ContractFactory>(
Contract: F,
args?: unknown[],
opts?: DeployContractOptions,
): Promise<ContractTypeOfFactory<F>>;
<F extends ContractFactory>(
Contract: ContractFactory,
opts?: DeployContractOptions,
): Promise<ContractTypeOfFactory<F>>;
}
async function deployNonUpgradeableContract(
hre: HardhatRuntimeEnvironment,
Contract: ContractFactory,
opts: DeployContractOptions,
connection: NetworkConnection,
): Promise<Required<Deployment> & DeployTransaction & RemoteDeploymentId> {
const deployData = await getDeployData(hre, Contract, opts, connection);
if (!opts.unsafeAllowDeployContract) {
assertNonUpgradeable(deployData);
}
const deployment: EthersOrDefenderDeployment = await deploy(
hre,
opts,
Contract,
...deployData.fullOpts.constructorArgs,
);
return deployment;
}
function assertNonUpgradeable(deployData: DeployData) {
const [fullContractName, runValidation] = getContractNameAndRunValidation(deployData.validations, deployData.version);
const c = runValidation[fullContractName];
if (inferInitializable(c) || inferProxyKind(deployData.validations, deployData.version) === 'uups') {
throw new UpgradesError(
`The contract ${fullContractName} looks like an upgradeable contract.`,
() =>
'Upgradable contracts cannot be deployed using the deployContract function. Use deployProxy, deployBeacon, or deployImplementation.\n' +
'If this is not intended to be an upgradeable contract, set the unsafeAllowDeployContract option to true and run the deployContract function again.',
);
}
}
export function makeDeployContract(
hre: HardhatRuntimeEnvironment,
defenderModule: boolean,
connection: NetworkConnection,
): DeployContractFunction {
return async function deployContract<F extends ContractFactory>(
Contract: F,
args: unknown[] | DeployContractOptions = [],
opts: DeployContractOptions = {},
): Promise<ContractTypeOfFactory<F>> {
if (!Array.isArray(args)) {
opts = args;
args = [];
}
opts = enableDefender(hre, defenderModule, opts);
if (!opts.useDefenderDeploy) {
throw new Error(`The ${deployContract.name} function cannot have the \`useDefenderDeploy\` option disabled.`);
}
if (opts.constructorArgs !== undefined) {
throw new Error(
`The ${deployContract.name} function does not support the constructorArgs option. Pass in constructor arguments using the format: deployContract(MyContract, [ 'my arg' ]);`,
);
}
opts.constructorArgs = args;
const deployment = await deployNonUpgradeableContract(hre, Contract, opts, connection);
return getContractInstance(hre, Contract, opts, deployment);
};
}