From 44f44075a8761b6259b987b7749385eef45536c9 Mon Sep 17 00:00:00 2001 From: Eric Lau Date: Tue, 24 Sep 2024 15:26:44 -0400 Subject: [PATCH] Update docs from Foundry Upgrades --- .../ROOT/pages/foundry/api/pages/Options.adoc | 3 ++ .../api/pages/api-foundry-upgrades.adoc | 34 ++++++++++++ .../pages/foundry/pages/foundry-upgrades.adoc | 54 +++++++++++-------- submodules/openzeppelin-foundry-upgrades | 2 +- 4 files changed, 71 insertions(+), 22 deletions(-) diff --git a/docs/modules/ROOT/pages/foundry/api/pages/Options.adoc b/docs/modules/ROOT/pages/foundry/api/pages/Options.adoc index eb71a5995..b150fcf6b 100644 --- a/docs/modules/ROOT/pages/foundry/api/pages/Options.adoc +++ b/docs/modules/ROOT/pages/foundry/api/pages/Options.adoc @@ -11,9 +11,12 @@ import { Options } from "openzeppelin-foundry-upgrades/Options.sol"; ```solidity struct Options { string referenceContract; + string referenceBuildInfoDir; bytes constructorData; + string[] exclude; string unsafeAllow; bool unsafeAllowRenames; + bool unsafeSkipProxyAdminCheck; bool unsafeSkipStorageCheck; bool unsafeSkipAllChecks; struct DefenderOptions defender; diff --git a/docs/modules/ROOT/pages/foundry/api/pages/api-foundry-upgrades.adoc b/docs/modules/ROOT/pages/foundry/api/pages/api-foundry-upgrades.adoc index d521c11d9..8d166f456 100644 --- a/docs/modules/ROOT/pages/foundry/api/pages/api-foundry-upgrades.adoc +++ b/docs/modules/ROOT/pages/foundry/api/pages/api-foundry-upgrades.adoc @@ -1,5 +1,39 @@ = OpenZeppelin Foundry Upgrades API +== Contract name formats + +Contract names must be provided in specific formats depending on context. The following are the required formats for each context: + +=== Foundry artifact format + +Contexts: + +* `contractName` parameter +* `referenceContract` option if `referenceBuildInfoDir` option is not set + +Can be in any of the following forms according to Foundry's https://book.getfoundry.sh/cheatcodes/get-code[getCode] cheatcode: + +* the Solidity file name, e.g. `ContractV1.sol` +* the Solidity file name and the contract name, e.g. `ContractV1.sol:ContractV1` +* the artifact path relative to the project root directory, e.g. `out/ContractV1.sol/ContractV1.json` + +=== Annotation format + +Contexts: + +* `@custom:oz-upgrades-from ` annotation +* `referenceContract` option if `referenceBuildInfoDir` option is set + +Can be in any of the following forms according to the https://docs.openzeppelin.com/upgrades-plugins/api-core#define-reference-contracts[OpenZeppelin Upgrades CLI]: + +* the contract name, e.g. `ContractV1` +* fully qualified contract name, e.g. `contracts/tokens/ContractV1.sol:ContractV1` + +If the `referenceBuildInfoDir` option is set, include the build info directory short name as a prefix, resulting in one of the following forms: + +* the build info directory short name and the contract name, e.g. `build-info-v1:ContractV1` +* the build info directory short name and the fully qualified contract name, e.g. `build-info-v1:contracts/tokens/ContractV1.sol:ContractV1` + == Common Options The following options can be used with some of the below functions. See https://github.com/OpenZeppelin/openzeppelin-foundry-upgrades/blob/main/src/Options.sol[Options.sol] for detailed descriptions of each option. diff --git a/docs/modules/ROOT/pages/foundry/pages/foundry-upgrades.adoc b/docs/modules/ROOT/pages/foundry/pages/foundry-upgrades.adoc index 0c3c2ee82..57290467e 100644 --- a/docs/modules/ROOT/pages/foundry/pages/foundry-upgrades.adoc +++ b/docs/modules/ROOT/pages/foundry/pages/foundry-upgrades.adoc @@ -133,10 +133,12 @@ import {MyToken} from "src/MyToken.sol"; Then call functions from the imported library to run validations, deployments, or upgrades. -=== Examples +== Examples The following examples assume you are using OpenZeppelin Contracts v5 and want to run upgrade safety validations. +=== Deploy a proxy + Deploy a UUPS proxy: [source,solidity] ---- @@ -156,6 +158,19 @@ address proxy = Upgrades.deployTransparentProxy( ); ---- +Deploy an upgradeable beacon and a beacon proxy: +[source,solidity] +---- +address beacon = Upgrades.deployBeacon("MyContract.sol", INITIAL_OWNER_ADDRESS_FOR_BEACON); + +address proxy = Upgrades.deployBeaconProxy( + beacon, + abi.encodeCall(MyContract.initialize, ("arguments for the initialize function")) +); +---- + +=== Use your contract + Call your contract's functions as normal, but remember to always use the proxy address: [source,solidity] ---- @@ -163,6 +178,8 @@ MyContract instance = MyContract(proxy); instance.myFunction(); ---- +=== Upgrade a proxy or beacon + Upgrade a transparent or UUPS proxy and call an arbitrary function (such as a reinitializer) during the upgrade process: [source,solidity] ---- @@ -183,37 +200,32 @@ Upgrades.upgradeProxy( ); ---- -WARNING: When upgrading a proxy or beacon, ensure that the new contract either has its `@custom:oz-upgrades-from ` annotation set to the current implementation contract used by the proxy or beacon, or set it with the `referenceContract` option, for example: -[source,solidity] ----- -Options memory opts; -opts.referenceContract = "MyContractV1.sol"; -Upgrades.upgradeProxy(proxy, "MyContractV2.sol", "", opts); -// or Upgrades.upgradeBeacon(beacon, "MyContractV2.sol", opts); ----- - -Deploy an upgradeable beacon: +Upgrade a beacon: [source,solidity] ---- -address beacon = Upgrades.deployBeacon("MyContract.sol", INITIAL_OWNER_ADDRESS_FOR_BEACON); +Upgrades.upgradeBeacon(beacon, "MyContractV2.sol"); ---- -Deploy a beacon proxy: +WARNING: When upgrading a proxy or beacon, ensure that the new contract either has its `@custom:oz-upgrades-from ` annotation set to the name of the old implementation contract used by the proxy or beacon, or set it with the `referenceContract` option, for example: [source,solidity] ---- -address proxy = Upgrades.deployBeaconProxy( - beacon, - abi.encodeCall(MyContract.initialize, ("arguments for the initialize function")) -); +Options memory opts; +opts.referenceContract = "MyContractV1.sol"; +Upgrades.upgradeProxy(proxy, "MyContractV2.sol", "", opts); +// or Upgrades.upgradeBeacon(beacon, "MyContractV2.sol", opts); ---- -Upgrade a beacon: +TIP: If possible, keep the old version of the implementation contract's source code somewhere in your project to use as a reference as above. This requires the new version to be in a different directory, Solidity file, or using a different contract name. Otherwise, if you want to use the same directory and name for the new version, keep the build info directory from the previous deployment (or build it from an older branch of your project repository) and reference it as follows: [source,solidity] ---- -Upgrades.upgradeBeacon(beacon, "MyContractV2.sol"); +Options memory opts; +opts.referenceBuildInfoDir = "/old-builds/build-info-v1"; +opts.referenceContract = "build-info-v1:MyContract"; +Upgrades.upgradeProxy(proxy, "MyContract.sol", "", opts); +// or Upgrades.upgradeBeacon(beacon, "MyContract.sol", opts); ---- -=== Coverage Testing +== Coverage Testing To enable code coverage reports with `forge coverage`, use the following deployment pattern in your tests: instantiate your implementation contracts directly and use the `UnsafeUpgrades` library. For example: ```solidity @@ -226,7 +238,7 @@ address proxy = Upgrades.deployUUPSProxy( WARNING: `UnsafeUpgrades` is not recommended for use in Forge scripts. It does not validate whether your contracts are upgrade safe or whether new implementations are compatible with previous ones. Ensure you run validations before any actual deployments or upgrades, such as by using the `Upgrades` library in scripts. -=== Deploying and Verifying +== Deploying and Verifying Run your script with `forge script` to broadcast and deploy. See Foundry's https://book.getfoundry.sh/tutorials/solidity-scripting[Solidity Scripting] guide. diff --git a/submodules/openzeppelin-foundry-upgrades b/submodules/openzeppelin-foundry-upgrades index b70222687..16e0ae21e 160000 --- a/submodules/openzeppelin-foundry-upgrades +++ b/submodules/openzeppelin-foundry-upgrades @@ -1 +1 @@ -Subproject commit b70222687c3a6b926e2ad9867b32567838bde939 +Subproject commit 16e0ae21e0e39049f619f2396fa28c57fad07368