0
# Proxy Patterns
1
2
OpenZeppelin provides comprehensive proxy patterns for creating upgradeable smart contracts including transparent proxies, beacon proxies, and minimal proxies. These patterns enable contract upgradeability while maintaining persistent storage and addresses.
3
4
## Capabilities
5
6
### Initializable - Upgradeable Contract Base
7
8
Base contract to aid in writing upgradeable contracts, ensuring initialization functions are only called once.
9
10
```solidity { .api }
11
/**
12
* This is a base contract to aid in writing upgradeable contracts
13
*/
14
abstract contract Initializable {
15
/**
16
* Modifier to protect an initializer function from being invoked twice
17
*/
18
modifier initializer();
19
20
/**
21
* Modifier to protect a function from being invoked after the contract has been initialized
22
*/
23
modifier onlyInitializing();
24
}
25
```
26
27
**Usage Example:**
28
29
```solidity
30
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
31
32
contract MyUpgradeableContract is Initializable {
33
uint256 private _value;
34
address private _owner;
35
36
function initialize(uint256 initialValue, address owner) public initializer {
37
_value = initialValue;
38
_owner = owner;
39
}
40
}
41
```
42
43
### Proxy - Base Proxy Contract
44
45
Abstract contract that implements a proxy pattern for upgradeable contracts.
46
47
```solidity { .api }
48
/**
49
* This abstract contract provides a fallback function that delegates all calls to another contract
50
*/
51
abstract contract Proxy {
52
/**
53
* Delegates the current call to implementation
54
*/
55
function _delegate(address implementation) internal virtual;
56
57
/**
58
* This is a virtual function that should be overridden so it returns the address to which the fallback function and _fallback should delegate
59
*/
60
function _implementation() internal view virtual returns (address);
61
62
/**
63
* Delegates the current call to the address returned by _implementation()
64
*/
65
function _fallback() internal virtual;
66
67
/**
68
* Fallback function that delegates calls to the address returned by _implementation()
69
*/
70
fallback() external payable virtual;
71
72
/**
73
* Fallback function that delegates calls to the address returned by _implementation()
74
*/
75
receive() external payable virtual;
76
}
77
```
78
79
### UpgradeableProxy - Basic Upgradeable Proxy
80
81
Upgradeable proxy that stores the implementation address in a specific storage slot.
82
83
```solidity { .api }
84
/**
85
* This contract implements an upgradeable proxy
86
*/
87
contract UpgradeableProxy is Proxy {
88
/**
89
* Initializes the upgradeable proxy with an initial implementation specified by implementation
90
*/
91
constructor(address _logic, bytes memory _data) payable;
92
93
/**
94
* Returns the current implementation address
95
*/
96
function _implementation() internal view virtual override returns (address impl);
97
98
/**
99
* Upgrades the proxy to a new implementation
100
*/
101
function _upgradeTo(address newImplementation) internal virtual;
102
103
/**
104
* Emitted when the implementation is upgraded
105
*/
106
event Upgraded(address indexed implementation);
107
}
108
```
109
110
### TransparentUpgradeableProxy - Admin-Controlled Proxy
111
112
Upgradeable proxy with an admin that can upgrade the implementation while preventing admin functions from being called by users.
113
114
```solidity { .api }
115
/**
116
* This contract implements a proxy that is upgradeable by an admin
117
*/
118
contract TransparentUpgradeableProxy is UpgradeableProxy {
119
/**
120
* Initializes an upgradeable proxy managed by admin, backed by the implementation at logic, and optionally initialized with data
121
*/
122
constructor(address logic, address admin, bytes memory data) payable UpgradeableProxy(logic, data);
123
124
/**
125
* Returns the current admin
126
*/
127
function admin() external view returns (address admin);
128
129
/**
130
* Returns the current implementation
131
*/
132
function implementation() external view returns (address implementation);
133
134
/**
135
* Changes the admin of the proxy
136
*/
137
function changeAdmin(address newAdmin) external;
138
139
/**
140
* Upgrade the implementation of the proxy
141
*/
142
function upgradeTo(address newImplementation) external;
143
144
/**
145
* Upgrade the implementation of the proxy, and then call a function from the new implementation
146
*/
147
function upgradeToAndCall(address newImplementation, bytes calldata data) external payable;
148
149
event AdminChanged(address previousAdmin, address newAdmin);
150
}
151
```
152
153
### ProxyAdmin - Proxy Administration
154
155
Administrative contract for managing multiple transparent upgradeable proxies.
156
157
```solidity { .api }
158
/**
159
* This is an auxiliary contract meant to be assigned as the admin of a TransparentUpgradeableProxy
160
*/
161
contract ProxyAdmin is Ownable {
162
/**
163
* Returns the current implementation of proxy
164
*/
165
function getImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address);
166
167
/**
168
* Changes the admin of proxy to newAdmin
169
*/
170
function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner;
171
172
/**
173
* Upgrades proxy to implementation
174
*/
175
function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner;
176
177
/**
178
* Upgrades proxy to implementation and calls a function on the new implementation
179
*/
180
function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner;
181
}
182
```
183
184
### BeaconProxy - Beacon-Based Proxy
185
186
Proxy that uses a beacon contract to determine its implementation address.
187
188
```solidity { .api }
189
/**
190
* This contract implements a proxy that gets the implementation address for each call from a UpgradeableBeacon
191
*/
192
contract BeaconProxy is Proxy, ERC1967Upgrade {
193
/**
194
* Initializes the proxy with beacon
195
*/
196
constructor(address beacon, bytes memory data) payable;
197
198
/**
199
* Returns the current beacon
200
*/
201
function _beacon() internal view virtual returns (address);
202
203
/**
204
* Returns the current implementation address of the associated beacon
205
*/
206
function _implementation() internal view virtual override returns (address);
207
208
/**
209
* Changes the proxy to use a new beacon
210
*/
211
function _setBeacon(address beacon, bytes memory data) internal virtual;
212
}
213
```
214
215
### UpgradeableBeacon - Implementation Beacon
216
217
Beacon contract that stores an implementation address and allows authorized accounts to upgrade it.
218
219
```solidity { .api }
220
/**
221
* This contract is used in conjunction with one or more instances of BeaconProxy to determine their implementation contract
222
*/
223
contract UpgradeableBeacon is IBeacon, Ownable {
224
/**
225
* Sets the address of the initial implementation, and the deployer account as the owner
226
*/
227
constructor(address implementation);
228
229
/**
230
* Returns the current implementation address
231
*/
232
function implementation() public view virtual override returns (address);
233
234
/**
235
* Upgrades the beacon to a new implementation
236
*/
237
function upgradeTo(address newImplementation) public virtual onlyOwner;
238
239
/**
240
* Emitted when the implementation returned by the beacon is changed
241
*/
242
event Upgraded(address indexed implementation);
243
}
244
```
245
246
### Clones - Minimal Proxy Factory
247
248
Library for deploying minimal proxy contracts (EIP-1167) that delegate all calls to a master contract.
249
250
```solidity { .api }
251
/**
252
* This library enables deploying and managing minimal proxy contracts
253
*/
254
library Clones {
255
/**
256
* Deploys and returns the address of a clone that mimics the behaviour of implementation
257
*/
258
function clone(address implementation) internal returns (address instance);
259
260
/**
261
* Deploys and returns the address of a clone that mimics the behaviour of implementation
262
* This function uses the create2 opcode and a salt to deterministically deploy the clone
263
*/
264
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance);
265
266
/**
267
* Computes the address of a clone deployed using Clones.cloneDeterministic
268
*/
269
function predictDeterministicAddress(
270
address implementation,
271
bytes32 salt,
272
address deployer
273
) internal pure returns (address predicted);
274
275
/**
276
* Computes the address of a clone deployed using Clones.cloneDeterministic
277
*/
278
function predictDeterministicAddress(address implementation, bytes32 salt) internal view returns (address predicted);
279
}
280
```
281
282
**Usage Example:**
283
284
```solidity
285
import "@openzeppelin/contracts/proxy/Clones.sol";
286
287
contract TokenFactory {
288
address immutable tokenImplementation;
289
290
constructor() {
291
tokenImplementation = address(new MyToken());
292
}
293
294
function createToken(string memory name, string memory symbol) external returns (address) {
295
address clone = Clones.clone(tokenImplementation);
296
MyToken(clone).initialize(name, symbol, msg.sender);
297
return clone;
298
}
299
}
300
```
301
302
## Upgrade Patterns
303
304
### Basic Upgrade Pattern
305
306
```solidity
307
// Implementation V1
308
contract MyContractV1 is Initializable {
309
uint256 private _value;
310
311
function initialize(uint256 initialValue) public initializer {
312
_value = initialValue;
313
}
314
315
function getValue() public view returns (uint256) {
316
return _value;
317
}
318
319
function setValue(uint256 newValue) public {
320
_value = newValue;
321
}
322
}
323
324
// Implementation V2 - adds new functionality
325
contract MyContractV2 is Initializable {
326
uint256 private _value;
327
uint256 private _multiplier; // New storage variable
328
329
function initialize(uint256 initialValue) public initializer {
330
_value = initialValue;
331
_multiplier = 1;
332
}
333
334
function getValue() public view returns (uint256) {
335
return _value * _multiplier;
336
}
337
338
function setValue(uint256 newValue) public {
339
_value = newValue;
340
}
341
342
// New function in V2
343
function setMultiplier(uint256 newMultiplier) public {
344
_multiplier = newMultiplier;
345
}
346
}
347
```
348
349
### Factory with Clones Pattern
350
351
```solidity
352
import "@openzeppelin/contracts/proxy/Clones.sol";
353
import "@openzeppelin/contracts/access/Ownable.sol";
354
355
contract TokenFactory is Ownable {
356
address public immutable tokenImplementation;
357
address[] public deployedTokens;
358
359
event TokenCreated(address indexed token, address indexed creator);
360
361
constructor(address _tokenImplementation) {
362
tokenImplementation = _tokenImplementation;
363
}
364
365
function createToken(
366
string memory name,
367
string memory symbol,
368
uint256 initialSupply
369
) external returns (address) {
370
bytes32 salt = keccak256(abi.encodePacked(msg.sender, name, symbol));
371
address tokenClone = Clones.cloneDeterministic(tokenImplementation, salt);
372
373
IToken(tokenClone).initialize(name, symbol, initialSupply, msg.sender);
374
375
deployedTokens.push(tokenClone);
376
emit TokenCreated(tokenClone, msg.sender);
377
378
return tokenClone;
379
}
380
381
function predictTokenAddress(
382
address creator,
383
string memory name,
384
string memory symbol
385
) external view returns (address) {
386
bytes32 salt = keccak256(abi.encodePacked(creator, name, symbol));
387
return Clones.predictDeterministicAddress(tokenImplementation, salt);
388
}
389
390
function getDeployedTokensCount() external view returns (uint256) {
391
return deployedTokens.length;
392
}
393
}
394
```
395
396
### Beacon Upgrade Pattern
397
398
```solidity
399
import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
400
import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
401
402
contract MyBeaconFactory is Ownable {
403
UpgradeableBeacon public immutable beacon;
404
address[] public deployedProxies;
405
406
constructor(address initialImplementation) {
407
beacon = new UpgradeableBeacon(initialImplementation);
408
}
409
410
function createProxy(bytes memory data) external returns (address) {
411
BeaconProxy proxy = new BeaconProxy(address(beacon), data);
412
deployedProxies.push(address(proxy));
413
return address(proxy);
414
}
415
416
function upgradeAll(address newImplementation) external onlyOwner {
417
beacon.upgradeTo(newImplementation);
418
// All deployed proxies now use the new implementation
419
}
420
421
function getCurrentImplementation() external view returns (address) {
422
return beacon.implementation();
423
}
424
}
425
```
426
427
### Complete Upgrade Workflow
428
429
```solidity
430
// 1. Deploy ProxyAdmin
431
ProxyAdmin proxyAdmin = new ProxyAdmin();
432
433
// 2. Deploy implementation contract
434
MyContractV1 implementationV1 = new MyContractV1();
435
436
// 3. Deploy proxy with initialization
437
bytes memory initData = abi.encodeWithSelector(
438
MyContractV1.initialize.selector,
439
123 // initial value
440
);
441
442
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
443
address(implementationV1),
444
address(proxyAdmin),
445
initData
446
);
447
448
// 4. Use proxy as if it were the implementation
449
MyContractV1 myContract = MyContractV1(address(proxy));
450
myContract.setValue(456);
451
452
// 5. Later, upgrade to V2
453
MyContractV2 implementationV2 = new MyContractV2();
454
proxyAdmin.upgrade(proxy, address(implementationV2));
455
456
// 6. Proxy now uses V2 implementation
457
MyContractV2 myContractV2 = MyContractV2(address(proxy));
458
myContractV2.setMultiplier(2);
459
```