# Errors

#### Errors in Solidity:

In Solidity, if something goes wrong inside a contract, rather than just failing silently, the contract can actively "revert" its state. This ensures that no changes made during the failed transaction persist in the blockchain. This concept of "reverting" or "throwing an error" is crucial because it means that a contract's state remains consistent and reliable despite any failed interactions.

Starting with Solidity version 0.8.4, there's an enhanced way to handle errors: the `error` construct. This allows developers to define custom errors with arguments, providing more descriptive feedback on what went wrong.

#### Example Contract:

```solidity
pragma solidity ^0.8.4;

contract TestToken {
    error InsufficientBalance(uint256 available, uint256 required);
    function transfer(address to, uint amount) public pure {
        revert InsufficientBalance(0, amount);
    }
}
```

The provided contract, `TestToken`, defines an error named `InsufficientBalance` which expects two `uint256` arguments - the available balance and the required balance. The `transfer` function in this contract always reverts the transaction using this error, signifying an insufficient balance.

When the `revert` statement with `InsufficientBalance(0, amount)` is executed, it generates "error data". This data encodes the error and its arguments similar to how data for a function call is encoded.

#### Error Encoding:

The example shows that if you tried to call the `transfer` function, the returned error data would be structured as if you called a function named `InsufficientBalance` with arguments `(0, amount)`.

1. `0xcf479181` is the function selector for `InsufficientBalance(uint256,uint256)`. It's generated from the first four bytes of the keccak256 hash of the error signature.
2. `uint256(0)` represents the first argument, which is the available balance.
3. `uint256(amount)` represents the second argument, which is the required balance.

#### Reserved Selectors:

The selectors `0x00000000` and `0xffffffff` are reserved for future use. A selector, in this context, is a unique identifier for a function or an error. By reserving these, Solidity is ensuring that no valid function or error will ever have these selectors, allowing them to be used for special purposes in the future.

#### Warning:

The warning is crucial for security reasons. It emphasizes two main points:

1. **Propagation of Errors**: If Contract A calls Contract B, and Contract B calls Contract C, and if Contract C throws an error, this error can bubble up and be caught by Contract A. Therefore, Contract A might encounter errors not defined in Contract B, the contract it directly interacts with.
2. **Faked Errors**: Any contract can generate error data that matches any error signature. This means a malicious contract might purposely throw misleading errors. It's a reminder to developers not to make trust decisions based solely on the error data they receive.

#### Summary:

Error handling in Solidity, especially with the enhanced `error` construct, provides developers with a clearer way to signify issues in contract execution. It ensures better communication of issues to the users and other interacting contracts. However, as with many aspects of smart contract development, it's essential to handle these errors with caution and awareness of potential pitfalls.
