0
# Proxy Patterns
1
2
OpenZeppelin Contracts provides comprehensive proxy patterns for creating upgradeable and flexible smart contract systems. These patterns enable contract upgradeability, gas-efficient contract cloning, and sophisticated deployment strategies.
3
4
## Core Imports
5
6
Import proxy contracts using Solidity import statements:
7
8
```solidity
9
import "@openzeppelin/contracts/proxy/Clones.sol";
10
import "@openzeppelin/contracts/proxy/Proxy.sol";
11
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
12
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
13
import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
14
import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
15
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
16
```
17
18
## Capabilities
19
20
### Minimal Proxy (EIP-1167)
21
22
Gas-efficient cloning of contracts using minimal proxy pattern. Creates lightweight proxy contracts that delegate all calls to a single implementation.
23
24
```solidity { .api }
25
library Clones {
26
function clone(address implementation) internal returns (address instance);
27
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance);
28
function predictDeterministicAddress(address implementation, bytes32 salt, address deployer) internal pure returns (address predicted);
29
function predictDeterministicAddress(address implementation, bytes32 salt) internal pure returns (address predicted);
30
}
31
```
32
33
#### Usage Example
34
35
```solidity
36
pragma solidity ^0.8.0;
37
38
import "@openzeppelin/contracts/proxy/Clones.sol";
39
40
contract TokenFactory {
41
address public immutable tokenImplementation;
42
43
constructor(address _tokenImplementation) {
44
tokenImplementation = _tokenImplementation;
45
}
46
47
function createToken(string memory name, string memory symbol) external returns (address) {
48
bytes32 salt = keccak256(abi.encodePacked(name, symbol, msg.sender));
49
address tokenClone = Clones.cloneDeterministic(tokenImplementation, salt);
50
51
// Initialize the cloned token
52
IToken(tokenClone).initialize(name, symbol, msg.sender);
53
54
return tokenClone;
55
}
56
57
function predictTokenAddress(string memory name, string memory symbol) external view returns (address) {
58
bytes32 salt = keccak256(abi.encodePacked(name, symbol, msg.sender));
59
return Clones.predictDeterministicAddress(tokenImplementation, salt);
60
}
61
}
62
```
63
64
### Base Proxy
65
66
Base proxy contract providing the foundation for all proxy patterns through delegate call functionality.
67
68
```solidity { .api }
69
abstract contract Proxy {
70
function _delegate(address implementation) internal virtual;
71
function _implementation() internal view virtual returns (address);
72
function _fallback() internal virtual;
73
function _beforeFallback() internal virtual;
74
}
75
```
76
77
### ERC-1967 Proxy Standard
78
79
Standard for upgradeable proxies with standardized storage slots for implementation addresses.
80
81
```solidity { .api }
82
contract ERC1967Proxy is Proxy, ERC1967Upgrade {
83
constructor(address _logic, bytes memory _data);
84
}
85
86
abstract contract ERC1967Upgrade {
87
function _getImplementation() internal view returns (address);
88
function _setImplementation(address newImplementation) internal;
89
function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal;
90
function _getAdmin() internal view returns (address);
91
function _setAdmin(address newAdmin) internal;
92
function _changeAdmin(address newAdmin) internal;
93
function _getBeacon() internal view returns (address);
94
function _setBeacon(address newBeacon) internal;
95
function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal;
96
}
97
```
98
99
### Transparent Upgradeable Proxy
100
101
Transparent proxy pattern that separates admin and user functions to avoid function selector clashes.
102
103
```solidity { .api }
104
contract TransparentUpgradeableProxy is ERC1967Proxy {
105
constructor(address _logic, address admin_, bytes memory _data);
106
}
107
108
contract ProxyAdmin is Ownable {
109
function getProxyImplementation(ITransparentUpgradeableProxy proxy) public view virtual returns (address);
110
function getProxyAdmin(ITransparentUpgradeableProxy proxy) public view virtual returns (address);
111
function changeProxyAdmin(ITransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner;
112
function upgrade(ITransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner;
113
function upgradeAndCall(ITransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner;
114
}
115
```
116
117
#### Usage Example
118
119
```solidity
120
pragma solidity ^0.8.0;
121
122
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
123
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
124
125
contract MyContractV1 is Initializable {
126
uint256 public value;
127
128
function initialize(uint256 _value) public initializer {
129
value = _value;
130
}
131
132
function setValue(uint256 _value) public {
133
value = _value;
134
}
135
}
136
137
// Deploy script would create:
138
// 1. Implementation: MyContractV1
139
// 2. ProxyAdmin: ProxyAdmin
140
// 3. Proxy: TransparentUpgradeableProxy(implementation, admin, initData)
141
```
142
143
### UUPS Upgradeable Pattern
144
145
User Upgradeable Proxy Standard where upgrade logic is in the implementation contract rather than the proxy.
146
147
```solidity { .api }
148
abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {
149
modifier onlyProxy();
150
modifier notDelegated();
151
152
function proxiableUUID() external view virtual override notDelegated returns (bytes32);
153
function upgradeTo(address newImplementation) external virtual onlyProxy;
154
function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual onlyProxy;
155
156
function _authorizeUpgrade(address newImplementation) internal virtual;
157
}
158
```
159
160
#### Usage Example
161
162
```solidity
163
pragma solidity ^0.8.0;
164
165
import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
166
import "@openzeppelin/contracts/access/Ownable.sol";
167
168
contract MyUUPSContract is UUPSUpgradeable, OwnableUpgradeable {
169
uint256 public value;
170
171
function initialize(uint256 _value) public initializer {
172
__Ownable_init();
173
__UUPSUpgradeable_init();
174
value = _value;
175
}
176
177
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
178
179
function setValue(uint256 _value) public {
180
value = _value;
181
}
182
}
183
```
184
185
### Beacon Proxy Pattern
186
187
Proxy pattern where multiple proxies delegate to the same beacon contract that holds the implementation address.
188
189
```solidity { .api }
190
contract BeaconProxy is Proxy, ERC1967Upgrade {
191
constructor(address beacon, bytes memory data);
192
}
193
194
contract UpgradeableBeacon is IBeacon, Ownable {
195
constructor(address implementation_);
196
197
function implementation() public view virtual override returns (address);
198
function upgradeTo(address newImplementation) public virtual onlyOwner;
199
function upgradeToAndCall(address newImplementation, bytes calldata data) public payable virtual onlyOwner;
200
}
201
202
interface IBeacon {
203
function implementation() external view returns (address);
204
}
205
```
206
207
#### Usage Example
208
209
```solidity
210
pragma solidity ^0.8.0;
211
212
import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
213
import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
214
215
contract TokenBeaconFactory {
216
UpgradeableBeacon public immutable beacon;
217
218
constructor(address tokenImplementation) {
219
beacon = new UpgradeableBeacon(tokenImplementation);
220
}
221
222
function createToken(string memory name, string memory symbol) external returns (address) {
223
bytes memory data = abi.encodeWithSelector(
224
IToken.initialize.selector,
225
name,
226
symbol,
227
msg.sender
228
);
229
230
return address(new BeaconProxy(address(beacon), data));
231
}
232
233
function upgradeAllTokens(address newImplementation) external {
234
beacon.upgradeTo(newImplementation);
235
}
236
}
237
```
238
239
### Initializable Pattern
240
241
Base contract for initialization logic in upgradeable contracts, replacing constructors which don't work with proxies.
242
243
```solidity { .api }
244
abstract contract Initializable {
245
modifier initializer();
246
modifier reinitializer(uint8 version);
247
modifier onlyInitializing();
248
249
function _disableInitializers() internal virtual;
250
function _getInitializedVersion() internal view returns (uint8);
251
function _isInitializing() internal view returns (bool);
252
}
253
```
254
255
## Proxy Pattern Best Practices
256
257
When implementing proxy patterns:
258
259
1. **Storage Layout**: Maintain storage layout compatibility between implementation versions
260
2. **Initialization**: Use `initializer` modifier instead of constructors for proxy-compatible contracts
261
3. **Admin Security**: Protect upgrade functions with proper access control
262
4. **Testing**: Test upgrade scenarios thoroughly, including storage layout changes
263
5. **Selector Clashes**: Be aware of potential function selector clashes in transparent proxies
264
6. **Gas Costs**: Consider gas costs of different proxy patterns for your use case
265
266
## Proxy Pattern Comparison
267
268
- **Minimal Proxy**: Cheapest deployment, immutable implementation
269
- **Transparent Proxy**: Most flexible, higher gas costs due to admin checks
270
- **UUPS**: Lower gas costs than transparent, upgrade logic in implementation
271
- **Beacon Proxy**: Best for multiple proxies sharing the same implementation
272
273
## Error Handling
274
275
Proxy contracts may revert with implementation-specific errors plus:
276
277
- **ERC1967Upgrade**: `ERC1967InvalidImplementation(address implementation)`, `ERC1967InvalidAdmin(address admin)`, `ERC1967InvalidBeacon(address beacon)`
278
- **UUPSUpgradeable**: `UUPSUpgradeable__Unauthorized()`, `UUPSUpgradeable__InvalidImplementation()`
279
- **Initializable**: `InvalidInitialization()`, `NotInitializing()`