20 Common Solidity Beginner Mistakes

20 Common Solidity Beginner Mistakes Our intent is not to be patronizing towards developers early in their journey with this article. Having reviewed code from numerous Solidity developers, we’ve seen some mistakes occur more frequently and we list those here. By no means is this an exhaustive list of mistakes a Solidity developer can make. […]

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 […]

Try Catch and all the ways Solidity can revert

Try Catch and all the ways Solidity can revert This article describes all the kinds of errors that can happen when a smart contract is called, and how the Solidity Try / Catch block responds (or fails to respond) to each of them. To understand how Try / Catch works in Solidity, we must understand […]

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 […]

Storage Slots in Solidity: Storage Allocation and Low-level assembly storage operations

Storage Slots in Solidity: Storage Allocation and Low-level assembly storage operations This article examines the storage architecture of the Ethereum Smart Contracts. It explains how variables are kept in the EVM storage and how to read and write to storage slots using low-level assembly (Yul). This information is a prerequisite to understanding how proxies in […]

Invariant Testing in Foundry

Invariant Testing in Foundry Introduction In this article, we will discuss invariants and how to perform an invariant test on solidity smart contracts using foundry test suites. Invariant testing is another test methodology like unit test and fuzzing to verify the correctness of code. If you are unfamiliar with unit tests, please see our article […]

Fixed Point Arithmetic in Solidity (Using Solady, Solmate, and ABDK as Examples)

Fixed Point Arithmetic in Solidity (Using Solady, Solmate, and ABDK as Examples) A fixed-point number is an integer that stores only the numerator of a fraction — while the denominator is implied. This type of arithmetic is not necessary in most programming languages because they have floating point numbers. It is necessary in Solidity because […]

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 […]

Understanding ABI encoding for function calls

Understanding ABI encoding for function calls ABI encoding is the data format used for making function calls to smart contracts. It is also how smart contracts encode data when making calls to other smart contracts. This guide will show how to interpret ABI encoded data, how to compute the ABI encoding, and teach the relationship […]

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 […]

Low Level Call vs High Level Call in Solidity

Low Level Call vs High Level Call in Solidity A contract in Solidity can call other contracts via two methods: through the contract interface, which is considered a high-level call, or by using the call method, which is a low-level approach. Despite both methods using the CALL opcode, Solidity handles them differently. In this article, we’ll compare […]

Three ways to detect if an address is a smart contract

Three ways to detect if an address is a smart contract This article describes three methods in Solidity for determining if an address is a smart contract: Check if msg.sender == tx.origin. This is not a recommended method, but because many smart contracts use it, we discuss this method for completeness. The second (and recommended […]

ERC-1363 Standard Explained

ERC-1363 Standard Explained ERC-1363 enables a smart contract to detect and respond to an incoming transfer of tokens. What problem does ERC-1363 Solve? Suppose a user transfers an ERC-20 token to a contract. The smart contract cannot credit the user for the transfer because it has no mechanism to see who made the transfer. Although […]

Understanding the Function Selector in Solidity

Understanding the Function Selector in Solidity The function selector is a 4 byte id that Solidity uses to identify functions under the hood. The function selector is how a Solidity contract knows which function you are trying to call in the transaction. You can see the 4 byte id using the .selector method: pragma solidity […]

How ERC721 Enumerable Works

How ERC721 Enumerable Works An Enumerable ERC721 is an ERC721 with added functionality that enables a smart contract to list all the NFTs an address owns. This article describes how ERC721Enumerable functions and how we can integrate it into an existing ERC721 project. We’ll use Open Zeppelin’s popular implementation of ERC721Enumerable for our explanation. Prerequisites […]

ERC20 Votes: ERC5805 and ERC6372

ERC20 Votes: ERC5805 and ERC6372 ERC20 Votes Knowledge of ERC20 Snapshot is assumed, please refer to our article on ERC20 Snapshot for an introduction to the subject. ERC20 Votes does not actually handle conducting the poll, it’s still a regular ERC20 token with snapshot and delegated voting abilities. Voting is usually handled by governance contracts. […]

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 second preimage attack for Merkle Trees in Solidity

The second preimage attack for Merkle Trees in Solidity The second preimage attack in Merkle trees can happen when an intermediate node in a merkle tree is presented as a leaf. The name of this attack is quite misleading because it implies hashes have a second preimage. Modern hash functions do not have multiple (computable) […]

A comprehensive guide to the ERC 721 standard and related security issues

A comprehensive guide to the ERC 721 standard and related security issues ERC721 (or ERC-721) is the most widely used Ethereum standard for nonfungible tokens. It associates a unique number with an Ethereum address, thereby denoting that address owns the unique number — the NFT. There is indeed no shortage of tutorials covering this famous […]

Ten beginner project ideas after you learn Solidity

Ten beginner project ideas after you learn Solidity Now that you”ve completed our solidity tutorial, what”s next? You now have enough knowledge to build any of the following projects. Knowledge comes by study, but skill comes with practice. You need both knowledge and skill if you want to be a successful solidity developer! Here are […]

The RareSkills Book of Solidity Gas Optimization: 80+ Tips

The RareSkills Book of Solidity Gas Optimization: 80+ Tips TABLE OF CONTENTS The RareSkills Book of Gas Optimization Gas optimization tricks do not always work Beware of complexity and readability Comprehensive treatment of each topic isn’t possible here We do not discuss application-specific tricks 1. Most important: avoid zero to one storage writes where possible […]

Solidity Coding Standards

Solidity Coding Standards The purpose of this article is not to rehash the official Solidity Style Guide, which you should read. Rather, it is to document the common deviations from the style guide that come up in code reviews or audits. Some of the items here are not in the style guide, but are common […]

How Tornado Cash Works (Line by Line for Devs)

How Tornado Cash Works (Line by Line for Devs) Introduction to Tornado Cash Tornado cash is a cryptocurrency smart contract mixer that enables users to deposit crypto with one address and withdraw with another wallet without creating a traceable link between those two addresses. Tornado cash is probably the most iconic zero knowledge smart contract […]

Getting a smart contract audit: what you need to know

Getting a smart contract audit: what you need to know A smart contract audit is a review by blockchain security experts to ensure that users will not lose funds due to a malfunction or security vulnerability. Furthermore, an audit tries to anticipate unexpected and undesirable smart contract behavior before the contract is deployed. Navigating this […]

Understanding smart contract metadata

Understanding smart contract metadata When solidity generates the bytecode for the smart contract to be deployed, it appends metadata about the compilation at the end of the bytecode. We will examine the data contained in this bytecode. A simple smart contract Let’s look at the compiler output of the simplest possible solidity smart contract //SPDX-License-Identifier: […]

Over 150 interview questions for Ethereum Developers

Over 150 interview questions for Ethereum Developers All of these questions can be answered in three sentences or less. Easy What is the difference between private, internal, public, and external functions? Approximately, how large can a smart contract be? What is the difference between create and create2? What major change with arithmetic happened with Solidity […]

Smart Contract Security

Smart Contract Security This article serves as a mini course on smart contract security and provides an extensive list of the issues and vulnerabilities that tend to recur in Solidity smart contracts. A security issue in Solidity boils down to smart contracts not behaving the way they were intended to. This can fall into four […]

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 […]

Ethereum precompiled contracts

Ethereum precompiled contracts Ethereum precompiles behave like smart contracts built into the Ethereum protocol. The nine precompiles live in addresses 0x01 to 0x09. The utility of precompiles falls into four categories – Elliptic curve digital signature recovery – Hash methods to interact with bitcoin and zcash – Memory copying – Methods to enable elliptic curve […]

Solidity Mutation Testing

Solidity Mutation Testing Mutation testing is a method to check the quality of the test suite by intentionally introducing bugs into the code and ensuring the tests catch the bug. The kind of bugs that get introduced are straightforward. Consider the following examples: // original function function mint() external payable { require(msg.value >= PRICE, "insufficient […]

Foundry Unit Tests

Foundry Unit Tests This article will describe how to create unit tests in Solidity using Foundry. We will cover how to test all the state transitions that can occur in a smart contract, plus some additional useful features Foundry provides. Foundry has very extensive testing capabilities, so rather than rehashing the documentation, we will focus […]

Solidity Staticcall EIP 214

Solidity Staticcall EIP 214 Staticcall is like a regular Ethereum call except that it reverts if a state change happens. It cannot be used to transfer Ether. Both the EVM opcode, the Yul assembly function, and the built-in solidity function named staticcall. EIP 214 Staticcall was introduced in EIP 214 added to Ethereum in 2017 […]

Openzeppelin Ownable: Use Ownable2Step Instead

Openzeppelin Ownable: Use Ownable2Step Instead The onlyOwner modifier is probably one of the most common patterns in Solidity. In the following example, the function setMessage() can only be called by the address designated to be the owner. function setMessage(string calldata _message) external onlyOwner { message = _message; } However, the commonly used Openzeppelin ownable implementation […]

Foundry forge coverage

Foundry forge coverage Visual line coverage report with LCOV If you run “forge coverage” in a foundry project, you’ll get a table showing how much of your lines and branches are covered. If you want to see visually which lines and branches are or are not covered, use the following steps Instructions to get line […]

Solidity test internal function

Solidity test internal function To test an internal solidity function, create a child contract that inherits from the contract being tested, wrap the parent contract’s internal function with an external one, then test the external function in the child. Foundry calls this inheriting contract a “harness” though others call it a “fixture.” Don’t change the […]

Uint256 max value

Uint256 max value The uint256 max value can be obtained with type(uint256).max; which is 115792089237316195423570985008687907853269984665640564039457584007913129639935 or 2²⁵⁶-1. But it’s cleaner and safer to use type(uint256).max. The same can be used for signed integer types //57896044618658097711785492504343953926634992332820282019728792003956564819967 type(int256).max; //-57896044618658097711785492504343953926634992332820282019728792003956564819968 type(int256).min; The math behind maximum values in integers and unsigned integers For unsigned integers, just put 2 ** […]

Solidity Events

Solidity Events Solidity events are the closest thing to a print or console.log statement in Ethereum. We will explain how they work, best practices for events, and go into a lot of technical details often omitted in other resources. Here is a minimal example to emit a solidity event. contract ExampleContract { // We will […]

Solidity Signed Integer

Solidity Signed Integer Solidity signed integers enable using negative numbers in a smart contract. This article documents how they are used at the EVM level. Basic familiarity with the EVM and binary numbers is assumed. Two’s Complement Explained Solidity and the EVM use Two’s Complement representation for signed integers Like every datatype, Solidity still uses […]

Verify Signature Solidity in Foundry

Verify Signature Solidity in Foundry Here is a minimal (copy and paste) example of how to safely create and verify ECDSA signatures with OpenZeppelin in the Foundry environment. Contract: Verifier.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; contract Verifier { using ECDSA for bytes32; address public verifyingAddress; constructor(address _verifyingAddress) { verifyingAddress = _verifyingAddress; } […]

EIP-3448 MetaProxy Standard: Minimal Proxy with support for immutable metadata

EIP-3448 MetaProxy Standard: Minimal Proxy with support for immutable metadata The minimal proxy standard allows us to parameterize the creation of the clone, but this requires an extra initialization transaction. It is possible to bypass this step entirely and parameterize the value we care about in the bytecode of the proxy, instead of using storage. […]

Governance Contract in Solidity

Governance Contract in Solidity The pattern of governance many DeFi applications follows is heavily inspired by Compound Finance’s implementation. Although, there isn’t an Ethereum Improvement Proposal related to create a standard governance interface, most DeFi governance implementations generally follow the same set of principles. Ultimately, governance contracts tend behave like multisignature wallets with votes weighted […]

ERC20 Snapshot

ERC20 Snapshot ERC20 Snapshot solves the problem of double voting. If votes are weighed by the number of tokens someone holds, then a malicious actor can use their tokens to vote, then transfer the tokens to another address, vote with that, and so forth. If each address is a smart contract, then the hacker can […]

EIP-1167: Minimal Proxy Standard with Initialization (Clone pattern)

EIP-1167: Minimal Proxy Standard with Initialization (Clone pattern) Image from https://pixabay.com/photos/stormtrooper-star-wars-lego-storm-2899993/ Introduction EIP-1167, which is also referred to as the minimal proxy contract, is a commonly used solidity pattern for cheaply creating proxy clones. If a use case requires deploying an identical contract (or very similar contract) repeatedly, this is a more gas efficient way […]

ERC4626 Interface Explained

ERC4626 Interface Explained ERC4626 is a tokenized vault standard that uses ERC20 tokens to represent shares of some other asset. How it works is you deposit one ERC20 token (token A) into the ERC4626 contract, and get another ERC20 token back, call it token S. In this example, token S represents your share of all […]

Ethereum smart contract creation code

Ethereum smart contract creation code 608060405260405160893803806089833981016040819052601e916025565b600055603d565b600060208284031215603657600080fd5b5051919050565b603f80604a6000396000f3fe6080604052600080fdfea26469706673582212204a131c1478e0e7bb29267fd8f6d38a660b40a25888982bd6618b720d4498b6b464736f6c634300080700330000000000000000000000000000000000000000000000000000000000000001 This article explains what happens at the bytecode level when an Ethereum smart contract is constructed and how the constructor arguments are interpreted. Table of contents We discuss the following topics with visual examples: Introduction Init code Payable constructor contract Non-payable constructor contract Runtime code Runtime code breakdown Constructor […]

Solidity Gasleft

Solidity Gasleft Introduction The purpose of this article is to describe the behavior of the solidity gasleft() function and its uses. It is a built-in function that is used to check the remaining gas during a contract call. It is one of the special variables and functions that always exist in the global namespace and […]

Solidity RSA signatures for aidrops and presales: Beating ECDSA and Merkle Trees in Gas Efficiency

Solidity RSA signatures for aidrops and presales: Beating ECDSA and Merkle Trees in Gas Efficiency Updated: Aug 4, 2023 By Suthan Somadeva and Michael Burke ECDSA Vs RSA Introduction Creating a contract that gives certain addresses permissions goes by several names: airdrops, presale, whitelist, allowlist, and so forth. But the essence of the idea is […]

Generate a random number with Solidity on the blockchain

Generate a random number with Solidity on the blockchain Random Number Randomness is tricky on the blockchain because the blockchain is deterministic, but randomness requires non-determinism (otherwise it becomes predictable). This article assumes the user has some familiarity with solidity already, especially the operations block.number(), block.hash(), and digital signatures. If you use data like block.timestamp […]

Solidity vs Rust

Solidity vs Rust A common misconception is that learning blockchain is about learning a new programming language. It isn’t. Learning blockchain is far more akin to learning a framework than a programming language. For example, just because you can program in python or go, it doesn’t automatically make you a frontend developer any more than […]