Read Our Books

Zero Knowledge Proofs Book

The most programmer friendly guide to building ZK-SNARKs from scratch

Read Now
Uniswap V2 Book

A deep dive into the source code, tokenomics, and math behind the most copied DeFi Protocol.

Read Now
Compound V3 Book

Learn the Compound Finance codebase and tokenomics in depth

Read Now
Proxy Patterns

The most comprehensive guide to smart contract upgradeability.

Read Now
Book of Gas Optimization

The web’s most authoritative and complete guide to Solidity Gas Optimization.

Read Now
Tornado Cash Book

The most comprehensive line-by-line guide to the iconic mixer - with animations

Read Now
60 Days of Solana

The Solana course is designed for engineers with a beginner or intermediate background.

Read Now
Smart Contract Security

A 2023 survey of how smart contracts break - over 12,000 words long

Read Now
Huff Puzzles

Learn the EVM hands on by programming in the most loved assembly language

Read Now
'RareSkills Riddles'

Capture the flag security exercises that even top security auditors struggle with

Read Now
Zero Knowledge Puzzles

Learn the Compound Finance codebase and tokenomics in depth

Read Now
Solidity Interview Questions

Interview questions top companies actually ask

Read Now
Learn Solidity 0.8 with Foundry

The complete Solidity course.

Read Now

Latest Articles

Storage Slot III (Complex Types)

Storage Slots of Dynamic Types (Mappings, Arrays, Strings, Bytes) Dynamic-sized types in Solidity (sometimes referred to as complex types) are data types with variable size. They include mappings, nested mappings, arrays, nested arrays, strings, bytes, and structs that contain any of those types. This article shows how they are encoded and kept in storage. Mappings […]

Assembly revert

Assembly revert Reverting transactions using inline assembly can be more gas-efficient than using the high-level Solidity revert or require statement. In this guide, we’ll explore how the different types of reverts in Solidity work under the hood by simulating their implementations in assembly. The example below shows that the revert statement in the assembly version […]

get_D() and get_y() in Curve StableSwap

get_D() and get_y() in Curve StableSwap This article shows algebraically step-by-step how the code for get_D() and get_y() are derived from the StableSwap invariant. Given the StableSwap Invariant: $$ An^n\sum x_i +D=An^nD+\frac{D^{n+1}}{n^n\prod x_i} $$ There are two frequent math operations we wish to conduct with it: Compute $D$ given fixed values for $A$, and the […]

Solidity

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

Cross Program Invocation In Anchor

Cross Program Invocation In Anchor Cross Program Invocation (CPI) is Solana’s terminology for a program calling the public function of another program. We’ve already done CPI before when we sent a transfer SOL transaction to the system program. Here is the relevant snippet by way of reminder: pub fn send_sol(ctx: Context<SendSol>, amount: u64) -> Result<()> […]

Reading Another Anchor Program’s Account Data On Chain

Reading Another Anchor Program’s Account Data On Chain In Solidity, reading another contract’s storage requires calling a view function or the storage variable being public. In Solana, an off-chain client can read a storage account directly. This tutorial shows how an on-chain Solana program can read the data in an account it does not own. […]

#[derive(Accounts)] in Anchor: different kinds of accounts

[derive(Accounts)] in Anchor: different kinds of accounts #[derive(Accounts)] in Solana Anchor is an attribute-like macro for structs that holds references to all the accounts the function will access during its execution. In Solana, every account the transaction will access must be specified in advance One reason Solana is so fast is that it executes transactions […]

Ethereum gas fee calculator

Gas To USD Ethereum Calculator

Use this calculator to predict the cost of an Ethereum transaction in dollars amounts. The calculator will even work if you enter the price of Ethereum in another currency. Just interpret the $-sign in your preferred currency

Try it Now

Zero Knowledge Proofs

The Intuition Behind ECDSA

The intuition behind elliptic curve digital signatures (ECDSA) This article explains how the ECDSA (Elliptic Curve Digital Signature Algorithm) works as well as why it works. We will incrementally “rediscover” the algorithm from first principles in this tutorial. Prerequisites We assume prior knowledge of Elliptic Curve Arithmetic Elliptic Curve Arithmetic in Finite Fields Digital Signature […]

Trusted Setup

Trusted Setup A trusted setup is a mechanism ZK-SNARKs use to evaluate a polynomial at a secret value. Observe that a polynomial $f(x)$ can be evaluated by computing the inner product of the coefficients with successive powers of $x$: For example, if $f(x)=3x^3+2x^2+5x+10$, then the coefficients are $[3,2,5,10]$ and we can compute the polynomial as […]

The Schwartz-Zippel Lemma and its application to Zero Knowledge Proofs

The Schwartz-Zippel Lemma and its application to Zero Knowledge Proofs Nearly all ZK-Proof algorithms rely on the Schwartz-Zippel Lemma to achieve succintness. The Schwartz-Zippel Lemma states that if we are given two polynomials $p(x)$ and $q(x)$ with degrees $d_p$ and $d_q$ respectively, and if $p(x) \neq q(x)$, then the number of points where $p(x)$ and […]

AliasCheck and Num2Bits_strict in Circomlib

AliasCheck and Num2Bits_strict in Circomlib An alias bug in Circom (or any ZK circuit language) occurs when a binary array of signals encodes a number larger than the field element can hold. We will refer to signals and field elements interchangeably in this article. We refer to the characteristic of the field as p. Loosely […]

Hacking Underconstrained Circom Circuits With Fake Proofs

Hacking Underconstrained Circom Circuits With Fake Proofs The <-- operator in Circom can be dangerous because it assigns values to signals but does not constrain them. But how do you actually exploit write a POC (proof of concept) for this vulnerability? We will be hacking the following circuit: pragma circom 2.1.8; template Mul3() { signal […]

Circom language tutorial with circomlib walkthrough

Circom language tutorial with circomlib walkthrough This tutorial introduces the Circom language and how to use it, along with common pitfalls. We will also explain a significant portion of the circomlib library in order to introduce common design patterns. A note about production use Circom is a fantastic tool for learning ZK-SNARKS. However, because it […]