Smart Contract Foundry Upgrades with the OpenZeppelin Plugin

Smart Contract Foundry Upgrades with the OpenZeppelin Plugin Upgrading a smart contract is a multistep and error-prone process, so to minimize the chances of human error, it is desirable to use a tool that automates the procedure as much as possible. Therefore, the OpenZeppelin Upgrade Plugin streamlines deploying, upgrading and managing smart contracts built with Foundry or […]

UUPS: Universal Upgradeable Proxy Standard (ERC-1822)

UUPS: Universal Upgradeable Proxy Standard (ERC-1822) The UUPS pattern is a proxy pattern where the upgrade function resides in the implementation contract, but changes the implementation address stored in the proxy contract via a delegatecall from the proxy. The high level mechanism is shown in the animation below: Similar to the Transparent Upgradeable Proxy, the […]

The Beacon Proxy Pattern Explained

The Beacon Proxy Pattern Explained A Beacon Proxy is a smart contract upgrade pattern where multiple proxies use the same implementation contract, and all the proxies can be upgraded in a single transaction. This article explains how this proxy pattern works. Prerequisites We are going to assume that you already know how a minimal proxy […]

ERC-7201 Storage Namespaces Explained

ERC-7201 Storage Namespaces Explained ERC-7201 (formerly EIP-7201) is a standard for grouping storage variables together by a common identifier called a namespace, and also to document the group of variables via NatSpec annotation. The purpose of the standard is to simplify managing storage variables during upgrades. Namespaces Namespaces are a common approach in programming languages […]

transparent-upgradeable-proxy

The Transparent Upgradeable Proxy Pattern Explained in Detail The Transparent Upgradeable Proxy is a design pattern for upgrading a proxy while eliminating the possibility of a function selector clash. A functional Ethereum proxy needs at least the following two features: A storage slot holding the address of the implementation contract A mechanism for an admin […]

Nodelegatecall Explained

Nodelegatecall Explained The nodelegatecall modifier prevents delegatecalls from being sent to a contract. We will first show the mechanism for how to accomplish this then later discuss the motivation for why one might do this. Below, we’ve simplified the nodelegatecall modifier originally created by Uniswap V3’s noDelegateCall: contract NoDelegateCallExample { address immutable private originalAddress; constructor() […]

Delegatecall: The Detailed and Animated Guide

Delegatecall: The Detailed and Animated Guide This article explains how delegatecall works in detail. The Ethereum Virtual Machine (EVM) offers four opcodes for making calls between contracts: CALL (F1) CALLCODE (F2) STATICCALL (FA) and DELEGATECALL (F4). Notably, the CALLCODE opcode has been deprecated since Solidity v5, being replaced by DELEGATECALL. These opcodes have a direct […]

The Fallback Extension Pattern

The Fallback Extension Pattern The fallback-extension pattern is a simple way to circumvent the 24kb smart contract size limit. Suppose we have functions foo() and bar() in our primary contract and wish to add baz() but cannot due to a lack of space. We add a fallback function to our primary smart contract that delegates […]

EIP 1967 Storage Slots for Proxies

EIP 1967 Storage Slots for Proxies EIP 1967 is a standard for where to store information that proxy contracts need to execute. Both the UUPS (Universal Upgradeable Proxy Standard) and the Transparent Upgradeable Proxy Pattern use it. Remember: EIP 1967 only states where certain storage variables go and what logs get emitted when they change, […]

The initializable smart contract design pattern

The initializable smart contract design pattern Initializers are how upgradeable contracts achieve the behavior of a constructor. When deploying contracts, it’s common to call a constructor to initialize storage variables. For example, a constructor might set the name of a token or the maximum supply. In an upgradeable contract, this information needs to be stored […]