Skip to content

Commit 60dc229

Browse files
authored
Update docs from Foundry Upgrades (#1084)
1 parent ed565f4 commit 60dc229

File tree

4 files changed

+71
-22
lines changed

4 files changed

+71
-22
lines changed

docs/modules/ROOT/pages/foundry/api/pages/Options.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ import { Options } from "openzeppelin-foundry-upgrades/Options.sol";
1111
```solidity
1212
struct Options {
1313
string referenceContract;
14+
string referenceBuildInfoDir;
1415
bytes constructorData;
16+
string[] exclude;
1517
string unsafeAllow;
1618
bool unsafeAllowRenames;
19+
bool unsafeSkipProxyAdminCheck;
1720
bool unsafeSkipStorageCheck;
1821
bool unsafeSkipAllChecks;
1922
struct DefenderOptions defender;

docs/modules/ROOT/pages/foundry/api/pages/api-foundry-upgrades.adoc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
= OpenZeppelin Foundry Upgrades API
22

3+
== Contract name formats
4+
5+
Contract names must be provided in specific formats depending on context. The following are the required formats for each context:
6+
7+
=== Foundry artifact format
8+
9+
Contexts:
10+
11+
* `contractName` parameter
12+
* `referenceContract` option if `referenceBuildInfoDir` option is not set
13+
14+
Can be in any of the following forms according to Foundry's https://book.getfoundry.sh/cheatcodes/get-code[getCode] cheatcode:
15+
16+
* the Solidity file name, e.g. `ContractV1.sol`
17+
* the Solidity file name and the contract name, e.g. `ContractV1.sol:ContractV1`
18+
* the artifact path relative to the project root directory, e.g. `out/ContractV1.sol/ContractV1.json`
19+
20+
=== Annotation format
21+
22+
Contexts:
23+
24+
* `@custom:oz-upgrades-from <reference>` annotation
25+
* `referenceContract` option if `referenceBuildInfoDir` option is set
26+
27+
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]:
28+
29+
* the contract name, e.g. `ContractV1`
30+
* fully qualified contract name, e.g. `contracts/tokens/ContractV1.sol:ContractV1`
31+
32+
If the `referenceBuildInfoDir` option is set, include the build info directory short name as a prefix, resulting in one of the following forms:
33+
34+
* the build info directory short name and the contract name, e.g. `build-info-v1:ContractV1`
35+
* the build info directory short name and the fully qualified contract name, e.g. `build-info-v1:contracts/tokens/ContractV1.sol:ContractV1`
36+
337
== Common Options
438

539
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.

docs/modules/ROOT/pages/foundry/pages/foundry-upgrades.adoc

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,12 @@ import {MyToken} from "src/MyToken.sol";
133133

134134
Then call functions from the imported library to run validations, deployments, or upgrades.
135135

136-
=== Examples
136+
== Examples
137137

138138
The following examples assume you are using OpenZeppelin Contracts v5 and want to run upgrade safety validations.
139139

140+
=== Deploy a proxy
141+
140142
Deploy a UUPS proxy:
141143
[source,solidity]
142144
----
@@ -156,13 +158,28 @@ address proxy = Upgrades.deployTransparentProxy(
156158
);
157159
----
158160

161+
Deploy an upgradeable beacon and a beacon proxy:
162+
[source,solidity]
163+
----
164+
address beacon = Upgrades.deployBeacon("MyContract.sol", INITIAL_OWNER_ADDRESS_FOR_BEACON);
165+
166+
address proxy = Upgrades.deployBeaconProxy(
167+
beacon,
168+
abi.encodeCall(MyContract.initialize, ("arguments for the initialize function"))
169+
);
170+
----
171+
172+
=== Use your contract
173+
159174
Call your contract's functions as normal, but remember to always use the proxy address:
160175
[source,solidity]
161176
----
162177
MyContract instance = MyContract(proxy);
163178
instance.myFunction();
164179
----
165180

181+
=== Upgrade a proxy or beacon
182+
166183
Upgrade a transparent or UUPS proxy and call an arbitrary function (such as a reinitializer) during the upgrade process:
167184
[source,solidity]
168185
----
@@ -183,37 +200,32 @@ Upgrades.upgradeProxy(
183200
);
184201
----
185202

186-
WARNING: When upgrading a proxy or beacon, ensure that the new contract either has its `@custom:oz-upgrades-from <reference>` annotation set to the current implementation contract used by the proxy or beacon, or set it with the `referenceContract` option, for example:
187-
[source,solidity]
188-
----
189-
Options memory opts;
190-
opts.referenceContract = "MyContractV1.sol";
191-
Upgrades.upgradeProxy(proxy, "MyContractV2.sol", "", opts);
192-
// or Upgrades.upgradeBeacon(beacon, "MyContractV2.sol", opts);
193-
----
194-
195-
Deploy an upgradeable beacon:
203+
Upgrade a beacon:
196204
[source,solidity]
197205
----
198-
address beacon = Upgrades.deployBeacon("MyContract.sol", INITIAL_OWNER_ADDRESS_FOR_BEACON);
206+
Upgrades.upgradeBeacon(beacon, "MyContractV2.sol");
199207
----
200208

201-
Deploy a beacon proxy:
209+
WARNING: When upgrading a proxy or beacon, ensure that the new contract either has its `@custom:oz-upgrades-from <reference>` 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:
202210
[source,solidity]
203211
----
204-
address proxy = Upgrades.deployBeaconProxy(
205-
beacon,
206-
abi.encodeCall(MyContract.initialize, ("arguments for the initialize function"))
207-
);
212+
Options memory opts;
213+
opts.referenceContract = "MyContractV1.sol";
214+
Upgrades.upgradeProxy(proxy, "MyContractV2.sol", "", opts);
215+
// or Upgrades.upgradeBeacon(beacon, "MyContractV2.sol", opts);
208216
----
209217

210-
Upgrade a beacon:
218+
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:
211219
[source,solidity]
212220
----
213-
Upgrades.upgradeBeacon(beacon, "MyContractV2.sol");
221+
Options memory opts;
222+
opts.referenceBuildInfoDir = "/old-builds/build-info-v1";
223+
opts.referenceContract = "build-info-v1:MyContract";
224+
Upgrades.upgradeProxy(proxy, "MyContract.sol", "", opts);
225+
// or Upgrades.upgradeBeacon(beacon, "MyContract.sol", opts);
214226
----
215227

216-
=== Coverage Testing
228+
== Coverage Testing
217229

218230
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:
219231
```solidity
@@ -226,7 +238,7 @@ address proxy = Upgrades.deployUUPSProxy(
226238

227239
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.
228240

229-
=== Deploying and Verifying
241+
== Deploying and Verifying
230242

231243
Run your script with `forge script` to broadcast and deploy. See Foundry's https://book.getfoundry.sh/tutorials/solidity-scripting[Solidity Scripting] guide.
232244

0 commit comments

Comments
 (0)