CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-openzeppelin--contracts

Secure Smart Contract library for Solidity with battle-tested implementations of token standards, access control, governance, and essential utilities for building decentralized applications.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

proxy-patterns.mddocs/

Proxy Patterns

Comprehensive upgradeability patterns enabling contract logic updates while preserving state and addresses, including transparent proxies, UUPS, beacon patterns, and minimal clones.

Capabilities

ERC1967 Proxy Standard

Core proxy implementation using standardized storage slots to prevent storage collisions in upgradeable contracts.

/**
 * @dev Utilities for ERC1967 proxy pattern with standardized storage slots
 */
library ERC1967Utils {
    /**
     * @dev Returns the current implementation address from storage
     */
    function getImplementation() internal view returns (address);
    
    /**
     * @dev Upgrades implementation and calls new contract with data
     */
    function upgradeToAndCall(address newImplementation, bytes memory data) internal;
    
    /**
     * @dev Returns the current admin address from storage
     */
    function getAdmin() internal view returns (address);
    
    /**
     * @dev Changes the admin of the proxy
     */
    function changeAdmin(address newAdmin) internal;
    
    /**
     * @dev Returns the current beacon address from storage
     */
    function getBeacon() internal view returns (address);
    
    /**
     * @dev Upgrades beacon and calls new implementation with data
     */
    function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal;
}

/**
 * @dev Basic ERC1967 proxy with upgradeable implementation storage
 */
contract ERC1967Proxy is Proxy {
    /**
     * @dev Initializes proxy with implementation and optional setup call
     */
    constructor(address implementation, bytes memory _data);
    
    /**
     * @dev Returns current implementation address from ERC1967 storage slot
     */
    function _implementation() internal view virtual override returns (address);
}

Transparent Upgradeable Proxy

Admin-controlled upgrade pattern that prevents function selector clashing between proxy and implementation.

/**
 * @dev Transparent proxy with separate admin for upgrade control
 */
contract TransparentUpgradeableProxy is ERC1967Proxy {
    /**
     * @dev Initializes transparent proxy with logic, admin, and setup data
     */
    constructor(address _logic, address initialOwner, bytes memory _data);
    
    /**
     * @dev Fallback implementing transparent pattern (admin vs user calls)
     */
    fallback() external payable virtual override;
}

/**
 * @dev Admin contract for managing transparent upgradeable proxies
 */
contract ProxyAdmin is Ownable {
    /**
     * @dev Current interface version for upgrade compatibility
     */
    string public constant UPGRADE_INTERFACE_VERSION = "5.0.0";
    
    /**
     * @dev Upgrades proxy to new implementation with initialization call
     */
    function upgradeAndCall(
        ITransparentUpgradeableProxy proxy,
        address implementation,
        bytes memory data
    ) public payable virtual onlyOwner;
}

Usage Example:

import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";

// Deploy implementation
MyContract implementation = new MyContract();

// Deploy proxy admin
ProxyAdmin admin = new ProxyAdmin(msg.sender);

// Deploy transparent proxy
bytes memory initData = abi.encodeCall(MyContract.initialize, (param1, param2));
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
    address(implementation),
    address(admin),
    initData
);

// Later upgrade through admin
MyContractV2 newImplementation = new MyContractV2();
admin.upgradeAndCall(
    ITransparentUpgradeableProxy(address(proxy)),
    address(newImplementation),
    ""
);

UUPS (Universal Upgradeable Proxy Standard)

Implementation-controlled upgrade pattern where the logic contract manages its own upgrades for gas efficiency.

/**
 * @dev UUPS upgradeable implementation with self-managed upgrades
 */
abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Utils {
    /**
     * @dev Upgrades implementation and calls new contract with data
     */
    function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy;
    
    /**
     * @dev Returns ERC1822 compatible UUID for this implementation
     */
    function proxiableUUID() external view virtual notDelegated returns (bytes32);
    
    /**
     * @dev Authorization function for upgrades (must be implemented by inheriting contract)
     */
    function _authorizeUpgrade(address newImplementation) internal virtual;
    
    /**
     * @dev Modifier ensuring execution only through proxy delegatecall
     */
    modifier onlyProxy();
    
    /**
     * @dev Modifier ensuring execution only in implementation context
     */
    modifier notDelegated();
}

Usage Example:

import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyUpgradeableContract is UUPSUpgradeable, OwnableUpgradeable {
    function initialize(address owner) public initializer {
        __Ownable_init(owner);
        __UUPSUpgradeable_init();
    }
    
    function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
}

// Deploy with ERC1967Proxy
MyUpgradeableContract implementation = new MyUpgradeableContract();
bytes memory initData = abi.encodeCall(MyUpgradeableContract.initialize, (owner));
ERC1967Proxy proxy = new ERC1967Proxy(address(implementation), initData);

// Upgrade through the proxy
MyUpgradeableContract proxyAsContract = MyUpgradeableContract(address(proxy));
MyUpgradeableContractV2 newImplementation = new MyUpgradeableContractV2();
proxyAsContract.upgradeToAndCall(address(newImplementation), "");

Beacon Proxy Pattern

Centralized upgrade mechanism where multiple proxies point to a single beacon for coordinated upgrades.

/**
 * @dev Beacon interface for implementation address resolution
 */
interface IBeacon {
    /**
     * @dev Returns the current implementation address
     */
    function implementation() external view returns (address);
}

/**
 * @dev Upgradeable beacon managing implementation for multiple proxies
 */
contract UpgradeableBeacon is IBeacon, Ownable {
    /**
     * @dev Returns current implementation address
     */
    function implementation() public view virtual returns (address);
    
    /**
     * @dev Upgrades implementation for all connected beacon proxies
     */
    function upgradeTo(address newImplementation) public virtual onlyOwner;
}

/**
 * @dev Proxy that gets implementation address from a beacon
 */
contract BeaconProxy is Proxy {
    /**
     * @dev Initializes proxy with beacon and optional setup call
     */
    constructor(address beacon, bytes memory data);
    
    /**
     * @dev Returns beacon address
     */
    function _getBeacon() internal view virtual returns (address);
    
    /**
     * @dev Returns implementation from beacon
     */
    function _implementation() internal view virtual override returns (address);
}

Usage Example:

// Deploy implementation and beacon
MyContract implementation = new MyContract();
UpgradeableBeacon beacon = new UpgradeableBeacon(address(implementation), owner);

// Deploy multiple beacon proxies
bytes memory initData = abi.encodeCall(MyContract.initialize, (param));
BeaconProxy proxy1 = new BeaconProxy(address(beacon), initData);
BeaconProxy proxy2 = new BeaconProxy(address(beacon), initData);

// Upgrade all proxies at once through beacon
MyContractV2 newImplementation = new MyContractV2();
beacon.upgradeTo(address(newImplementation));

Minimal Clones (EIP-1167)

Ultra-lightweight, non-upgradeable proxy pattern for cost-efficient contract deployment via clone factories.

/**
 * @dev Library for creating minimal proxy clones (EIP-1167)
 */
library Clones {
    /**
     * @dev Creates clone using CREATE opcode
     */
    function clone(address implementation) internal returns (address instance);
    
    /**
     * @dev Creates clone using CREATE2 with deterministic address
     */
    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance);
    
    /**
     * @dev Creates clone with immutable arguments appended
     */
    function cloneWithImmutableArgs(address implementation, bytes memory args) internal returns (address instance);
    
    /**
     * @dev Predicts address for deterministic clone
     */
    function predictDeterministicAddress(
        address implementation,
        bytes32 salt,
        address deployer
    ) internal pure returns (address predicted);
    
    /**
     * @dev Retrieves immutable arguments from clone instance
     */
    function fetchCloneArgs(address instance) internal pure returns (bytes memory args);
}

Usage Example:

import "@openzeppelin/contracts/proxy/Clones.sol";

contract TokenFactory {
    address public immutable implementation;
    
    constructor() {
        implementation = address(new MyToken());
    }
    
    function createToken(string memory name, string memory symbol) external returns (address) {
        // Create minimal clone
        address clone = Clones.clone(implementation);
        
        // Initialize the clone
        MyToken(clone).initialize(name, symbol, msg.sender);
        
        return clone;
    }
    
    function createDeterministicToken(
        string memory name,
        string memory symbol,
        bytes32 salt
    ) external returns (address) {
        // Create deterministic clone
        address clone = Clones.cloneDeterministic(implementation, salt);
        MyToken(clone).initialize(name, symbol, msg.sender);
        return clone;
    }
}

Proxy Initialization

Safe initialization patterns for proxy contracts preventing double-initialization and supporting versioned upgrades.

/**
 * @dev Initialization utility for proxy contracts with version support
 */
abstract contract Initializable {
    /**
     * @dev Disables initializers (use in implementation constructor)
     */
    function _disableInitializers() internal virtual;
    
    /**
     * @dev Returns current initialized version
     */
    function _getInitializedVersion() internal view returns (uint64);
    
    /**
     * @dev Returns true if currently in initialization phase
     */
    function _isInitializing() internal view returns (bool);
    
    /**
     * @dev Modifier allowing single initialization (version 1)
     */
    modifier initializer();
    
    /**
     * @dev Modifier allowing versioned re-initialization
     */
    modifier reinitializer(uint64 version);
    
    /**
     * @dev Modifier restricting access to initialization phase only
     */
    modifier onlyInitializing();
}

Usage Example:

import "@openzeppelin/contracts/proxy/utils/Initializable.sol";

contract MyUpgradeableContract is Initializable {
    string public name;
    address public owner;
    
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }
    
    function initialize(string memory _name, address _owner) public initializer {
        name = _name;
        owner = _owner;
    }
    
    function initializeV2(string memory _name, address _owner, uint256 _newFeature) public reinitializer(2) {
        name = _name;
        owner = _owner;
        // Initialize new features for V2
    }
}

Base Proxy Implementation

Abstract proxy contract providing core delegation functionality for all proxy patterns.

/**
 * @dev Abstract proxy contract with core delegation logic
 */
abstract contract Proxy {
    /**
     * @dev Returns implementation address (must be implemented by inheriting contracts)
     */
    function _implementation() internal view virtual returns (address);
    
    /**
     * @dev Performs delegatecall to implementation
     */
    function _delegate(address implementation) internal virtual;
    
    /**
     * @dev Internal fallback logic
     */
    function _fallback() internal virtual;
    
    /**
     * @dev External fallback function
     */
    fallback() external payable virtual;
    
    /**
     * @dev Receive function for ETH transfers
     */
    receive() external payable virtual;
}

Types

/**
 * @dev ERC-1967 standardized storage slots
 */
bytes32 constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
bytes32 constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
bytes32 constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;

/**
 * @dev ERC-1822 Universal Upgradeable Proxy Standard interface
 */
interface IERC1822Proxiable {
    /**
     * @dev Returns the storage slot used by the implementation
     */
    function proxiableUUID() external view returns (bytes32);
}

/**
 * @dev ERC-1967 Proxy Storage Slots interface
 */
interface IERC1967 {
    event Upgraded(address indexed implementation);
    event AdminChanged(address previousAdmin, address newAdmin);
    event BeaconUpgraded(address indexed beacon);
}

/**
 * @dev Transparent upgradeable proxy interface
 */
interface ITransparentUpgradeableProxy is IERC1967 {
    function upgradeToAndCall(address newImplementation, bytes calldata data) external payable;
}

Install with Tessl CLI

npx tessl i tessl/npm-openzeppelin--contracts

docs

access-control.md

account-abstraction.md

finance.md

governance.md

index.md

mathematical-utilities.md

meta-transactions.md

proxy-patterns.md

security-utilities.md

token-standards.md

tile.json