⛏️Informational Vulnerability 11: `require` vs `assert`
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()
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()
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
assert()
for InvariantsSince assert()
consumes all remaining gas, it’s best utilized for internal invariant checks where failure indicates a significant issue in the contract logic.
Using require()
for Input Validation and External Calls
require()
for Input Validation and External Callsrequire()
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.
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.
Last updated