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

60 lines • 3.62 kB
import { getAdminAddress, getCode, getUpgradeInterfaceVersion, isEmptySlot } from '@openzeppelin/upgrades-core'; import { deployProxyImpl } from './deploy-impl.js'; import { encodeCall } from './initializer-data.js'; import { iTransparentUpgradeableProxyV4Abi, iTransparentUpgradeableProxyV5Abi, proxyAdminV4Abi, proxyAdminV5Abi, } from './artifacts.js'; import defaultDebug from '../utils/debug.js'; /** * Client-neutral orchestration of `upgradeProxy`: deploys (or reuses) the new implementation, * then sends the upgrade transaction to the proxy or its admin, choosing the right entrypoint * based on the on-chain upgrade interface version. Returns the upgrade transaction. */ export async function upgradeProxy(binding, proxyAddress, implInfo, opts, log = defaultDebug) { const { impl: nextImpl } = await deployProxyImpl(binding, implInfo, opts, proxyAddress); const call = encodeCall(binding, implInfo.abi, opts.call); const upgrade = await resolveUpgrade(binding, proxyAddress, log); const sent = await upgrade(nextImpl, call); return { proxyAddress, sent }; } async function resolveUpgrade(binding, proxyAddress, log) { const provider = binding.provider; const adminAddress = await getAdminAddress(provider, proxyAddress); const adminBytecode = await getCode(provider, adminAddress); const send = (to, abi, fn, args) => binding.sendTransaction({ to, data: binding.encodeFunctionData(abi, fn, args) }); if (isEmptySlot(adminAddress) || adminBytecode === '0x') { // No admin contract: use ITransparentUpgradeableProxy to get the proxiable interface const upgradeInterfaceVersion = await getUpgradeInterfaceVersion(provider, proxyAddress, log); switch (upgradeInterfaceVersion) { case '5.0.0': { return (nextImpl, call) => send(proxyAddress, iTransparentUpgradeableProxyV5Abi, 'upgradeToAndCall', [nextImpl, call ?? '0x']); } default: { if (upgradeInterfaceVersion !== undefined) { // Log as debug if the interface version is an unknown string. // Do not throw an error because this could be caused by a fallback function. log(`Unknown UPGRADE_INTERFACE_VERSION ${upgradeInterfaceVersion} for proxy at ${proxyAddress}. Expected 5.0.0`); } return (nextImpl, call) => call ? send(proxyAddress, iTransparentUpgradeableProxyV4Abi, 'upgradeToAndCall', [nextImpl, call]) : send(proxyAddress, iTransparentUpgradeableProxyV4Abi, 'upgradeTo', [nextImpl]); } } } else { // Admin contract: redirect the upgrade call through it const upgradeInterfaceVersion = await getUpgradeInterfaceVersion(provider, adminAddress, log); switch (upgradeInterfaceVersion) { case '5.0.0': { return (nextImpl, call) => send(adminAddress, proxyAdminV5Abi, 'upgradeAndCall', [proxyAddress, nextImpl, call ?? '0x']); } default: { if (upgradeInterfaceVersion !== undefined) { log(`Unknown UPGRADE_INTERFACE_VERSION ${upgradeInterfaceVersion} for proxy admin at ${adminAddress}. Expected 5.0.0`); } return (nextImpl, call) => call ? send(adminAddress, proxyAdminV4Abi, 'upgradeAndCall', [proxyAddress, nextImpl, call]) : send(adminAddress, proxyAdminV4Abi, 'upgrade', [proxyAddress, nextImpl]); } } } } //# sourceMappingURL=upgrade-proxy.js.map