Replace revert strings with custom errors by ernestognw · Pull Request #4261 · OpenZeppelin/openzeppelin-contracts (original) (raw)

I want to touch again on the "where errors are declared", because I fell we never took the proper time to discuss the options. We discuss the syntax of the error at length, but I think there is more to it than just how they are named. Particularly since our codebase is designed to be reused.


AFAIK, there are 4 options to declaring errors

I don't really like defining them globally, because it pollutes the namespace, and can cause to identifier conflicts very easily (particularly if there are many errors)

For contracts vs interfaces vs library, there is the following:


In our codebase, we use (custom) errors in different cases:


IMO there is real value to having clear "error" libraries, as it would improve reusing the errors in helper libraries (SafeERC20), or between contracts if/when that makes sens. All the libraries errors are already declared within the libraries, which IMO is good! Now its just a matter of moving the errors declared in contracts to dedicated libraries.

Example n°1:

I would propose that in the contracts/governance folder, next to Governor.sol and IGovernor.sol we have GovernorErrors.sol that would contain library GovernorErrors {...} and could be reused accross the code.
In particular, this file would declare all the errors for the Governor system, including the one that are used in modules but not in the core. Since 0.8.20, only the ones actually used would be part of the compiled in the ABI. So no more errors scaterred all over the modules with possible duplicates, and cleaner ABIs for the contracts.

Example n°2:

For ERC20 (and the other tokens), I would add a contracts/token/ERC20/ERC20Errors.sol that contains library ERC20Errors {...}. Note that while it doesn't match the reference implementation of ERC6093 (which we could update) it complies with the ERC, because nowhere does the ERC state that the errros must be in an interface (in the end they would be in the contract ABI just the same).
The contracts/interfaces/draft-ERC6093.sol could be built similarly to to other in this repo

pragma solidity ^0.8.0;

import "../token/ERC20/ERC20Errors.sol";
import "../token/ERC721/ERC721Errors.sol";
import "../token/ERC1155/ERC1155Errors.sol";

What do you think?

EDIT: my point includes a direct consequence, the pragma should be no lower than 0.8.20 so the custom errors get in the ABI