Post-it notes on a white background.
Breaking DownAssert vs. Require
January 25th, 2021

Overview of Assert and Require

When deciding between when to make use of assert versus require, one must consider two key factors in their deliberation: gas efficiency and bytecode analysis.

The functions Assert() and Require() may be used to check specified conditions are met and consequently throw an exception in the event the condition is not met.

  • Assert() should only be used to test for internal errors, and to check invariants.

  • Require() should be used to ensure valid conditions are met that cannot be detected until execution time.

You may optionally provide a message for require, but not for assert.

Examples of internal errors include: dividing by zero, converting a oversized value, allocating too much memory, or accessing a storage byte array that is incorrectly encoded.

Examples of valid conditions include: message sender must be the owner, the balance of a user must be at least the deposited amount, or the allowance must be at least the amount being sent.

Gas Efficiency

assert(false) compiles to 0xfe, an invalid opcode, thus using up all remaining gas, this because the assert function creates an error type Panic(uint256).

require(false) compiles to 0xfd, the revert opcode, thus refunding the remaining gas.

Bytecode Analysis

When used as intended, analysis tools may identify conditions wherein which function calls result in a failing assert, which should never be the case in properly-functioning code — if this happens there exists a bug.

Implementing Require()

Validate User Inputs: such as require a user inputs a value above or below a specified amount or only for a certain asset.

Validate State Conditions: prior to executing state changing operations, for example in an owned contract.

Require() is more commonly used than Assert(): in fact, I hardly ever use assert and when I do it is for good reason, also, conventionally, require statements are used at the beginning of a function.

Implementing Assert()

Checking for Overflow or Underflow: these are both arithmetic errors.

Checking Invariants: cases where the anticipated change does not occur.

Validating Contract State: ensuring anticipated state post-changes.

Assert is ccommonly used at the end of functions: we use it primarily as a means to prevent anything really bad from happening.