Skip to main content

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.

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

address private _rescuer
Private state variable storing the address of the current rescuer.

Functions

rescueERC20

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 Example:
// Rescue 1000 USDC tokens accidentally sent to the contract
rescuable.rescueERC20(
    IERC20(0xUSDC_ADDRESS),
    0xRECOVERY_ADDRESS,
    1000 * 10**6 // 1000 USDC (6 decimals)
);

updateRescuer

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

rescuer

function rescuer() external view returns (address)
Returns the address of the current rescuer. Returns: Address of the current rescuer Source: Rescuable.sol:40

Internal Functions

_updateRescuer

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

Modifiers

onlyRescuer

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

Events

RescuerChanged

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

// 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
using SafeERC20 for IERC20;
Source: Rescuable.sol:30

Origin

Forked from Centre USDC Rescuable with modifications:
  • Updated Solidity version from 0.6.12 to 0.7.6
  • Added internal _updateRescuer function

Build docs developers (and LLMs) love