or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

access-control.mdcrosschain.mdfinance.mdgovernance.mdindex.mdmetatx.mdproxy.mdsecurity.mdtokens.mdutilities.md

proxy.mddocs/

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()`