UNPKG

@openzeppelin/hardhat-upgrades

Version:

[![Docs](https://img.shields.io/badge/docs-%F0%9F%93%84-blue)](https://docs.openzeppelin.com/upgrades-plugins/hardhat-upgrades) [![NPM Package](https://img.shields.io/npm/v/@openzeppelin/hardhat-upgrades.svg)](https://www.npmjs.org/package/@openzeppelin/h

90 lines • 4.92 kB
import { fetchOrDeploy, fetchOrDeployGetDeployment, getStorageLayout, getUnlinkedBytecode, getVersion, UpgradesError, } from '@openzeppelin/upgrades-core'; import { withDefaults } from './options.js'; import { validateBeaconImpl, validateProxyImpl, validateImpl } from './validate-impl.js'; import { readValidations } from '../utils/validations.js'; export async function getDeployData(binding, info, opts) { const provider = binding.provider; const validations = await readValidations(binding.hre); const unlinkedBytecode = getUnlinkedBytecode(validations, info.bytecode); const encodedArgs = binding.encodeConstructorArgs(info, opts.constructorArgs ?? []); const version = getVersion(unlinkedBytecode, info.bytecode, encodedArgs); const layout = getStorageLayout(validations, version); const fullOpts = withDefaults(opts); return { provider, validations, unlinkedBytecode, encodedArgs, version, layout, fullOpts }; } export async function deployUpgradeableImpl(binding, info, opts, currentImplAddress) { const deployData = await getDeployData(binding, info, opts); await validateImpl(deployData, opts, currentImplAddress); return await deployImpl(binding, deployData, info, opts); } export async function deployProxyImpl(binding, info, opts, proxyAddress) { const deployData = await getDeployData(binding, info, opts); await validateProxyImpl(deployData, opts, proxyAddress); if (opts.kind === undefined) { throw new Error('Broken invariant: Proxy kind is undefined'); } return { ...(await deployImpl(binding, deployData, info, opts)), kind: opts.kind, }; } export async function deployBeaconImpl(binding, info, opts, beaconAddress) { const deployData = await getDeployData(binding, info, opts); await validateBeaconImpl(deployData, opts, beaconAddress); return await deployImpl(binding, deployData, info, opts); } async function deployImpl(binding, deployData, info, opts) { const layout = deployData.layout; if (opts.useDeployedImplementation && opts.redeployImplementation !== undefined) { throw new UpgradesError('The useDeployedImplementation and redeployImplementation options cannot both be set at the same time'); } const merge = deployData.fullOpts.redeployImplementation === 'always'; // The deploy callback is only invoked when a new deployment is actually performed; when an // existing deployment is reused from the manifest, `deployed` stays undefined and the // transaction response is reconstructed from the manifest's txHash by the binding. let deployed; const deployment = await fetchOrDeployGetDeployment(deployData.version, deployData.provider, async () => { const abi = binding.formatManifestAbi(info.abi); const attemptDeploy = () => { if (deployData.fullOpts.useDeployedImplementation || deployData.fullOpts.redeployImplementation === 'never') { throw new UpgradesError('The implementation contract was not previously deployed.', () => { if (deployData.fullOpts.useDeployedImplementation) { return 'The useDeployedImplementation option was set to true but the implementation contract was not previously deployed on this network.'; } else { return "The redeployImplementation option was set to 'never' but the implementation contract was not previously deployed on this network."; } }); } else { return binding.deployUnconfirmed(info, deployData.fullOpts.constructorArgs); } }; deployed = await attemptDeploy(); return { abi, ...deployed, layout }; }, opts, merge, binding.getRemoteDeployment); const result = { address: deployment.address, txHash: deployment.txHash, deployTransaction: deployed?.deployTransaction, remoteDeploymentId: 'remoteDeploymentId' in deployment ? deployment.remoteDeploymentId : undefined, }; return { impl: deployment.address, deployment: result }; } /** * To import an already deployed contract we reuse fetchOrDeploy for its ability to validate a * deployment and record it in the network file, by "simulating" a deployment: the deploy callback * simply returns the contract to be imported rather than deploying anything. */ export async function simulateDeployImpl(binding, info, opts, implAddress) { const deployData = await getDeployData(binding, info, opts); const simulateDeploy = async () => { return { abi: binding.formatManifestAbi(info.abi), layout: deployData.layout, address: implAddress, }; }; await fetchOrDeploy(deployData.version, deployData.provider, simulateDeploy, opts, true); } //# sourceMappingURL=deploy-impl.js.map