hardhat icon indicating copy to clipboard operation
hardhat copied to clipboard

Added a guide for using upgradeable proxies with hardhat ignition

Open zoeyTM opened this issue 1 year ago • 5 comments

Follows along with the example added in here

zoeyTM avatar Dec 18 '23 06:12 zoeyTM

⚠️ No Changeset found

Latest commit: f797a4920cd1c69c3cdc1a75e13c845746983fb8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

changeset-bot[bot] avatar Dec 18 '23 06:12 changeset-bot[bot]

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
hardhat ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 24, 2024 4:13am

vercel[bot] avatar Dec 18 '23 06:12 vercel[bot]

This is a really good first pass. Thinking about the structure, I think we should move away from a straight description of the code towards:

  • write initial module
  • hook up to test
  • modify deployment to upgrade the contract
  • look the test code keeps the same structure (but the version changed)!

What do you think?

kanej avatar Dec 18 '23 16:12 kanej

Part of the structure of this is what do we think our advice would be best practice for upgrading open zeppelin contracts using Ignition?

The pattern in the code is nested modules where upgradeV2 uses deployV1; there is an extent to which I miss being able to express passing parameters:

const {proxy: proxyV1, proxyAdmin} = m.useModule(DeployV1, {})
const {proxy: proxyV2} = m.useModule(UpgradeToV2, {proxyAdmin})
...
const {proxy: proxyVX} = m.useMOdule(UpgradeToVX, {proxyAdmin})

return {proxy: proxyVX}

Maybe we can achieve the same thing internally within one module with plain functions, so something like:

const upgrade = (m: ModuleBuilder, proxyAdmin, proxyAdminOwner, contractName: string) => {
  const instance = m.contract(contractName);

  m.call(proxyAdmin, "upgradeAndCall", [proxy, demoV2, "0x"], {
    from: proxyAdminOwner,
  });

  const updatedProxy = m.contractAt(contractName, proxy);

  return updatedProxy;
}

cont module = buildModule((m) => {
  const proxyAdminOwner = m.getAccount(1);
  const {proxy: proxyV1, proxyAdmin} = m.useModule(DeployV1, {});

  upgrade(m, poxyAdmin, proxyAdminOwner, "DemoV2");
  // ...
  const proxyVX = upgrade(m, poxyAdmin, proxyAdminOwner, "DemoVX");

  return {proxy: proxyVX}
})

The key point being to make the "I need to upgrade the contract to the next version" problem as concise to express as possible.

kanej avatar Dec 18 '23 16:12 kanej

@kanej

Part of the structure of this is what do we think our advice would be best practice for upgrading open zeppelin contracts using Ignition?

My opinion is that, long or even medium term, none of this will be our recommended best practice for upgradeable proxy patterns in Ignition. The reason for that is because I think we can do better, whether that comes in the form of an UpgradeableProxyStrategy or some other abstraction, similar to or inspired by OpenZeppelin's hardhat-upgrades plugin.

My understanding was that this guide and the accompanying sample project were only meant to show how a user could leverage Ignition's current API to support their upgradeable proxy needs (mostly demonstrating how to use m.contractAt(...), to be entirely honest) since a more complete solution is not in our immediate roadmap.

Additionally, there are other upgradeable contract patterns out there, and individual implementations can vary widely. My goal was to demonstrate the specific parts of the API that allow for upgradeable proxies to work in Ignition today and to explain why they are used how they are to enable users to apply those tools and logic to their own upgradeable contract system, whatever that may look like.

zoeyTM avatar Dec 19 '23 01:12 zoeyTM