@openzeppelin/hardhat-upgrades
Version:
[](https://docs.openzeppelin.com/upgrades-plugins/hardhat-upgrades) [](https://www.npmjs.org/package/@openzeppelin/h
60 lines • 3.62 kB
JavaScript
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