# Informational Vulnerability 11: \`require\` vs \`assert\`

{% hint style="info" %}
[**Book an audit with Zokyo**](https://www.zokyo.io/)
{% endhint %}

### **Introduction**

In Solidity, ensuring the correctness of a smart contract is crucial. Error handling mechanisms such as `assert()` and `require()` are vital tools that developers use to enforce correctness, validate external inputs, and handle errors in contracts. This tutorial aims to provide a clear understanding of when and how to use `assert()` and `require()` effectively in Solidity contracts, aiding in writing secure and robust code.

### **Exploring `assert()` and `require()`**

#### **1. Syntax and Usage**

**`assert(condition)`**

* Utilized to handle internal errors and check invariants within a contract.
* Consumes all remaining gas when the condition fails.

**`require(condition, message)`**

* Primarily used for input validation and external contract call checks.
* Refunds the remaining gas when the condition is not met.
* Allows for an optional error message to be added, enhancing error clarity.

#### **2. When to Use `assert()` vs `require()`**

**Using `assert()`**

`assert()` should be used to handle conditions that must always be true. These are fundamental invariants of your contract, and if they fail, it typically signifies a bug in the contract.

**Using `require()`**

`require()` is suitable for handling runtime errors. It’s commonly used to validate user inputs, ensuring conditions are met before execution, and validating responses from external contract calls.

### **Best Practices and Guidelines**

#### **Using `assert()` for Invariants**

Since `assert()` consumes all remaining gas, it’s best utilized for internal invariant checks where failure indicates a significant issue in the contract logic.

```solidity
solidityCopy codepragma solidity ^0.8.0;

contract AssertExample {
    uint256 public storedData;

    function set(uint256 x) public {
        storedData = x;
    }

    function verifyInvariant() public view {
        assert(storedData != 0);
    }
}
```

#### **Using `require()` for Input Validation and External Calls**

`require()` is more flexible due to its ability to refund unused gas and provide error messages. It should be the primary choice for validating external inputs and conditions.

```solidity
solidityCopy codepragma solidity ^0.8.0;

contract RequireExample {
    function transfer(address recipient, uint256 amount) public {
        require(recipient != address(0), "Invalid recipient");
        require(amount > 0, "Amount must be positive");
        // transfer logic here
    }
}
```

### **Conclusion**

Choosing between `assert()` and `require()` should be a deliberate decision based on the nature of the condition being checked. Utilize `assert()` for invariants and internal error checks where failure represents a bug. On the other hand, employ `require()` for validating external inputs and handling runtime errors, taking advantage of its gas refund capabilities and descriptive error messages. By following these guidelines and understanding the implications of `assert()` and `require()`, developers can enhance the reliability and robustness of their Solidity contracts.
