> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/circlefin/evm-cctp-contracts/llms.txt
> Use this file to discover all available pages before exploring further.

# Rescuable

> Emergency recovery of ERC20 tokens locked in contracts

The `Rescuable` contract provides emergency functionality to recover ERC20 tokens that are accidentally sent to or locked in CCTP contracts. This is a safety mechanism to prevent permanent loss of funds.

**Contract:** `src/roles/Rescuable.sol`

## Key Concepts

* **Rescuer Role**: Authorized address that can rescue locked ERC20 tokens
* **Emergency Recovery**: Allows withdrawal of tokens that shouldn't be in the contract
* **Owner Control**: Only the owner can assign the rescuer role

## State Variables

### \_rescuer

```solidity theme={null}
address private _rescuer
```

Private state variable storing the address of the current rescuer.

## Functions

### rescueERC20

```solidity theme={null}
function rescueERC20(
    IERC20 tokenContract,
    address to,
    uint256 amount
) external onlyRescuer
```

Rescues ERC20 tokens locked in the contract by transferring them to a specified address.

**Parameters:**

* `tokenContract`: Address of the ERC20 token contract to rescue
* `to`: Recipient address to receive the rescued tokens
* `amount`: Amount of tokens to rescue

**Requirements:**

* Caller must be the rescuer
* Contract must have sufficient token balance
* Token transfer must succeed

**Source:** [Rescuable.sol:58](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/roles/Rescuable.sol#L58)

**Example:**

```solidity theme={null}
// Rescue 1000 USDC tokens accidentally sent to the contract
rescuable.rescueERC20(
    IERC20(0xUSDC_ADDRESS),
    0xRECOVERY_ADDRESS,
    1000 * 10**6 // 1000 USDC (6 decimals)
);
```

### updateRescuer

```solidity theme={null}
function updateRescuer(address newRescuer) external onlyOwner
```

Assigns the rescuer role to a new address.

**Parameters:**

* `newRescuer`: Address of the new rescuer

**Requirements:**

* Caller must be the owner
* New rescuer must be non-zero address

**Emits:** `RescuerChanged(address indexed newRescuer)`

**Source:** [Rescuable.sol:70](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/roles/Rescuable.sol#L70)

### rescuer

```solidity theme={null}
function rescuer() external view returns (address)
```

Returns the address of the current rescuer.

**Returns:** Address of the current rescuer

**Source:** [Rescuable.sol:40](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/roles/Rescuable.sol#L40)

## Internal Functions

### \_updateRescuer

```solidity theme={null}
function _updateRescuer(address newRescuer) internal
```

Internal function to update the rescuer role.

**Parameters:**

* `newRescuer`: Address of the new rescuer

**Requirements:**

* New rescuer must be non-zero address

**Emits:** `RescuerChanged(address indexed newRescuer)`

**Source:** [Rescuable.sol:78](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/roles/Rescuable.sol#L78)

## Modifiers

### onlyRescuer

```solidity theme={null}
modifier onlyRescuer()
```

Restricts function access to the rescuer only.

**Reverts:** "Rescuable: caller is not the rescuer" if caller is not the rescuer

**Source:** [Rescuable.sol:47](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/roles/Rescuable.sol#L47)

## Events

### RescuerChanged

```solidity theme={null}
event RescuerChanged(address indexed newRescuer)
```

Emitted when the rescuer role is transferred to a new address.

**Parameters:**

* `newRescuer`: Address of the new rescuer

## Usage Example

```solidity theme={null}
// Set initial rescuer (as owner)
rescuable.updateRescuer(0xRESCUER_ADDRESS);

// Check current rescuer
address currentRescuer = rescuable.rescuer();

// Rescue accidentally sent tokens (as rescuer)
rescuable.rescueERC20(
    IERC20(0xTOKEN_ADDRESS),
    0xRECOVERY_ADDRESS,
    amount
);
```

## Use Cases

### When to Use Rescue

1. **Accidental Transfers**: Users accidentally send tokens directly to the contract address
2. **Unsupported Tokens**: Tokens other than those officially supported by CCTP end up in the contract
3. **Operational Errors**: Tokens become stuck due to failed operations
4. **Protocol Upgrades**: Recovery needed during migration or upgrade scenarios

### When NOT to Use Rescue

* **Do not rescue tokens** that are part of normal protocol operations (e.g., tokens held for pending burns/mints)
* **Do not rescue tokens** that belong to users as part of legitimate deposits
* The rescue function should only be used for truly locked or mistakenly sent funds

## Security Considerations

* The rescuer role is separate from the owner role for operational flexibility
* Only the owner can change the rescuer address
* Uses OpenZeppelin's SafeERC20 library to handle tokens safely
* The rescuer should be a trusted address (e.g., multisig or DAO)
* Rescuing tokens does not affect the contract's paused state
* Consider implementing governance or timelock mechanisms for rescue operations
* Log all rescue operations for transparency and auditability

## Implementation Details

### SafeERC20 Usage

The contract uses OpenZeppelin's `SafeERC20` library, which:

* Handles tokens that don't return a boolean on transfer
* Reverts on failed transfers instead of returning false
* Provides protection against common ERC20 implementation issues

```solidity theme={null}
using SafeERC20 for IERC20;
```

**Source:** [Rescuable.sol:30](https://github.com/circlefin/evm-cctp-contracts/blob/master/src/roles/Rescuable.sol#L30)

## Origin

Forked from [Centre USDC Rescuable](https://github.com/centrehq/centre-tokens/blob/0d3cab14ebd133a83fc834dbd48d0468bdf0b391/contracts/v1.1/Rescuable.sol) with modifications:

* Updated Solidity version from 0.6.12 to 0.7.6
* Added internal `_updateRescuer` function
