# CallbackHandler

**Inherits:** ICallbackHandler

Handles callback validation and execution for vault operations. This contract is designed to be used as a mixin in BaseVault, providing the ability to register logic for safely handling callbacks during guardian submissions. A common use case for handlers is receiving a flash loan. To receive a flashloan, the vault has to cede control when requesting a flashloan and then atomically handle the callback to repay the flashloan This requires two capabilities: the ability to register new handlers and the ability to initiate additional operations in the handle while being restricted by the merkle tree constraints. The callback handler contract achieves this by allowing guardians to "prepare" for a callback when they construct a given operation. If the operation "has a callback" then the fallback function in this contract will handle it. It will use transient storage to preserve information such as the expected callback caller, function selector of the callback and any approvals that are created during the callback

*Uses transient storage to manage callback state and approvals*

## State Variables

### CALLBACK\_CALL\_SLOT

ERC7201-compliant transient storage slot for storing the next authorized selector + caller

*Equal to keccak256(abi.encode(uint256(keccak256("aera.callbackHandler.call")) - 1)) & \~bytes32(uint256(0xff));*

**Note:** security: Critical for callback validation

```solidity
bytes32 internal constant CALLBACK_CALL_SLOT = 0xa48fd101fc9f41f09dc754b3b14722487070ffbd61259b49558564a3296a3f00;
```

### CALLBACK\_MERKLE\_ROOT\_SLOT

ERC7201-compliant transient storage slot for storing the callback merkle root

*Equal to keccak256(abi.encode(uint256(keccak256("aera.callbackHandler.merkleRoot")) - 1) & \~bytes32(uint256(0xff));*

**Note:** security: Critical for callback validation

```solidity
bytes32 internal constant CALLBACK_MERKLE_ROOT_SLOT = 0x30fb041442610fd0a22e4654f60ea1c715088ef7320b5ec0c4e75cbdd99dbe00;
```

### APPROVALS\_SLOT

ERC7201-compliant transient storage slot for storing the approval tracking

*Equal to keccak256(abi.encode(uint256(keccak256("aera.callbackHandler.approvals")) - 1)) & \~bytes32(uint256(0xff));*

**Note:** security: Critical for tracking token approvals during callbacks

```solidity
bytes32 internal constant APPROVALS_SLOT = 0xba2cfcc1b17a97110b1fb218b61c42c0e510c6913e669a69d4ade619ace66c00;
```

## Functions

### fallback

Handle incoming callbacks and validates their authorization

*Extracts callback data and forwards to \_handleCallbackOperations if valid*

```solidity
fallback(bytes calldata) external returns (bytes memory returnValue);
```

### \_handleCallbackOperations

Internal handler for validated callbacks

*Callback operations are like regular operations, but with a return value, which are encoded after operations array ┌─────────────────────────────┬─────────────────────────┬───────────────────────────────────────────────┐ │ FIELDS │ SIZE │ DESCRIPTION │ ├─────────────────────────────┴─────────────────────────┴───────────────────────────────────────────────┤ │ returnTypeFlag 1 byte 0 = no return, 1 = static, 2 = dynamic │ │ \[if returnTypeFlag == 1]: │ │ returnDataLength 2 bytes Length of return data │ │ returnData bytes Static return data │ └───────────────────────────────────────────────────────────────────────────────────────────────────────┘*

```solidity
function _handleCallbackOperations(bytes32 root, uint256 cursor) internal virtual returns (bytes memory returnValue);
```

**Parameters**

| Name     | Type      | Description                     |
| -------- | --------- | ------------------------------- |
| `root`   | `bytes32` | The merkle root of the callback |
| `cursor` | `uint256` | The cursor to the callback data |

**Returns**

| Name          | Type    | Description                      |
| ------------- | ------- | -------------------------------- |
| `returnValue` | `bytes` | The return value of the callback |

### \_allowCallback

Whitelist a function selector and caller as a valid callback

*Uses transient storage to store the callback data*

```solidity
function _allowCallback(bytes32 root, uint256 packedCallbackData) internal;
```

**Parameters**

| Name                 | Type      | Description                                          |
| -------------------- | --------- | ---------------------------------------------------- |
| `root`               | `bytes32` | The merkle root of the callback                      |
| `packedCallbackData` | `uint256` | Packed data containing caller, selector, and offsets |

### \_storeCallbackApprovals

Store approvals for the current callback context

*Uses transient storage to track approvals during callback execution*

*Length of the array, packed with the token address will be stored in the first slot*

*All other elements are laid out sequentially after the first slot, taking 2 slots per approval*

*If there are existing approvals, we will update length in the slot zero and append new approvals*

```solidity
function _storeCallbackApprovals(Approval[] memory approvals, uint256 length) internal;
```

**Parameters**

| Name        | Type         | Description                       |
| ----------- | ------------ | --------------------------------- |
| `approvals` | `Approval[]` | Array of token approvals to store |
| `length`    | `uint256`    | Length of the array               |

### \_getAllowedCallback

Retrieve the currently allowed callback data

*Store packed token and length in the zero slot, and spender in the second*

*Update the length and preserve the token in the zero slot Minus one to compensate for pre-increment in upcoming storage loop*

*Unpacks data from transient storage*

**Note:** security: Critical for callback validation

```solidity
function _getAllowedCallback() internal returns (address caller, bytes4 selector, uint16 userDataOffset);
```

**Returns**

| Name             | Type      | Description                                   |
| ---------------- | --------- | --------------------------------------------- |
| `caller`         | `address` | The authorized caller address                 |
| `selector`       | `bytes4`  | The authorized function selector              |
| `userDataOffset` | `uint16`  | The offset in calldata where user data begins |

### \_getAllowedMerkleRoot

Retrieves the currently allowed merkle root

*Unpacks data from transient storage*

**Note:** security: Critical for callback validation

```solidity
function _getAllowedMerkleRoot() internal returns (bytes32 root);
```

**Returns**

| Name   | Type      | Description                |
| ------ | --------- | -------------------------- |
| `root` | `bytes32` | The authorized merkle root |

### \_getCallbackApprovals

Retrieves the current callback approvals

*Decodes approvals from transient storage*

*The first slot contains the length of the array, packed with the token address*

*All other elements are laid out sequentially after the first slot, taking 2 slots per approval*

*Only length slot is cleared, the rest of the approvals are left in the transient storage*

*This is safe because even if new approvals are added, old ones will be overwritten for length slots*

```solidity
function _getCallbackApprovals() internal returns (Approval[] memory approvals);
```

**Returns**

| Name        | Type         | Description                      |
| ----------- | ------------ | -------------------------------- |
| `approvals` | `Approval[]` | Array of current token approvals |

### \_hasCallbackBeenCalled

Checks if an expected callback has been called

*If callback was expected but not received, CALLBACK\_CALL\_SLOT will not be reset to 0*

```solidity
function _hasCallbackBeenCalled() internal view returns (bool);
```

**Returns**

| Name     | Type   | Description                                                   |
| -------- | ------ | ------------------------------------------------------------- |
| `<none>` | `bool` | True if an expected callback has been called, false otherwise |

### \_unpackCallbackData

Unpacks callback data from a packed uint256

```solidity
function _unpackCallbackData(uint256 packed)
    private
    pure
    returns (address target, bytes4 selector, uint16 dataOffset);
```

**Parameters**

| Name     | Type      | Description                                 |
| -------- | --------- | ------------------------------------------- |
| `packed` | `uint256` | The packed uint256 containing callback data |

**Returns**

| Name         | Type      | Description                                   |
| ------------ | --------- | --------------------------------------------- |
| `target`     | `address` | The target address                            |
| `selector`   | `bytes4`  | The function selector                         |
| `dataOffset` | `uint16`  | The offset in calldata where user data begins |

### \_packLengthAndToken

Packs a token address and length into a uint256

*Used in transient storage slot zero*

*`length` is required to be less than `type(uint96).max + 1`*

```solidity
function _packLengthAndToken(uint256 length, address token) private pure returns (uint256);
```

**Parameters**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `length` | `uint256` | The length of the approvals array |
| `token`  | `address` | The token address                 |

**Returns**

| Name     | Type      | Description               |
| -------- | --------- | ------------------------- |
| `<none>` | `uint256` | packed The packed uint256 |
