> ## 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.

# TokenMessengerV2

> Sends and receives token burn/mint messages with fee support and hook execution

## Overview

`TokenMessengerV2` is responsible for facilitating cross-chain USDC transfers by burning tokens on the source domain and minting them on the destination domain. V2 introduces fee mechanisms, finality thresholds, and optional hook execution.

**Contract Location**: `src/v2/TokenMessengerV2.sol`

## Key Features

### New Features vs V1

1. **Fee Mechanism**: Support for destination domain fees with `maxFee` parameter
2. **Minimum Fee Control**: Configurable minimum fee requirements in basis points
3. **Finality Thresholds**: Messages can specify minimum finality requirements
4. **Hook Execution**: Optional `hookData` for custom logic on destination domain
5. **Destination Caller**: Specify authorized caller on destination domain
6. **Denylist Support**: Ability to denylist addresses from using the protocol

## Constructor

```solidity theme={null}
constructor(
    address _messageTransmitter,
    uint32 _messageBodyVersion
)
```

### Parameters

* `_messageTransmitter` (address): Message transmitter address
* `_messageBodyVersion` (uint32): Message body version

## Initialization

```solidity theme={null}
struct TokenMessengerV2Roles {
    address owner;
    address rescuer;
    address feeRecipient;
    address denylister;
    address tokenMinter;
    address minFeeController;
}

function initialize(
    TokenMessengerV2Roles calldata roles,
    uint256 minFee_,
    uint32[] calldata remoteDomains_,
    bytes32[] calldata remoteTokenMessengers_
) external
```

Initializes the contract with roles and configuration.

**Reference**: `src/v2/TokenMessengerV2.sol:109`

### Parameters

* `roles` (TokenMessengerV2Roles): Struct containing all role addresses
  * `owner`: Owner address (cannot be zero)
  * `rescuer`: Rescuer address
  * `feeRecipient`: Address to receive collected fees
  * `denylister`: Address with permission to manage denylist
  * `tokenMinter`: Local token minter address
  * `minFeeController`: Address with permission to set minimum fee
* `minFee_` (uint256): Initial minimum fee (in 1/1000 basis points)
* `remoteDomains_` (uint32\[]): Array of remote domain IDs
* `remoteTokenMessengers_` (bytes32\[]): Array of remote TokenMessenger addresses (must match remoteDomains\_ length)

### Requirements

* Owner must be non-zero address
* Remote domains and remote token messengers arrays must have equal length
* All remote token messenger addresses must be non-zero

## Core Functions

### depositForBurn

```solidity theme={null}
function depositForBurn(
    uint256 amount,
    uint32 destinationDomain,
    bytes32 mintRecipient,
    address burnToken,
    bytes32 destinationCaller,
    uint256 maxFee,
    uint32 minFinalityThreshold
) external
```

Deposits and burns tokens from sender to be minted on destination domain.

**Reference**: `src/v2/TokenMessengerV2.sol:166`

#### Parameters

* `amount` (uint256): Amount of tokens to burn (must be nonzero)
* `destinationDomain` (uint32): Destination domain to receive message on
* `mintRecipient` (bytes32): Address of mint recipient on destination domain
* `burnToken` (address): Token to burn `amount` of, on local domain
* `destinationCaller` (bytes32): Authorized caller on the destination domain as bytes32. If equal to `bytes32(0)`, any address can broadcast the message
* `maxFee` (uint256): Maximum fee to pay on the destination domain, specified in units of burnToken
* `minFinalityThreshold` (uint32): The minimum finality at which the burn message will be attested to

#### Requirements

* Caller must not be denylisted
* Amount must be nonzero
* Mint recipient must be nonzero
* Burn token must be supported
* Destination domain must have a TokenMessenger registered
* `maxFee` must be less than `amount`
* `maxFee` must be >= `amount * minFee / MIN_FEE_MULTIPLIER` (if minFee > 0)
* Sender must have sufficient balance and approval

#### Events

```solidity theme={null}
event DepositForBurn(
    address indexed burnToken,
    uint256 amount,
    address indexed depositor,
    bytes32 mintRecipient,
    uint32 destinationDomain,
    bytes32 destinationTokenMessenger,
    bytes32 destinationCaller,
    uint256 maxFee,
    uint32 indexed minFinalityThreshold,
    bytes hookData
);
```

### depositForBurnWithHook

```solidity theme={null}
function depositForBurnWithHook(
    uint256 amount,
    uint32 destinationDomain,
    bytes32 mintRecipient,
    address burnToken,
    bytes32 destinationCaller,
    uint256 maxFee,
    uint32 minFinalityThreshold,
    bytes calldata hookData
) external
```

Deposits and burns tokens with optional hook data for execution on destination domain.

**Reference**: `src/v2/TokenMessengerV2.sol:210`

#### Parameters

Same as `depositForBurn`, plus:

* `hookData` (bytes): Hook data to append to burn message for interpretation on destination domain (must be non-empty)

#### Requirements

Same as `depositForBurn`, plus:

* `hookData` must have length > 0

### handleReceiveFinalizedMessage

```solidity theme={null}
function handleReceiveFinalizedMessage(
    uint32 remoteDomain,
    bytes32 sender,
    uint32 finalityThresholdExecuted,
    bytes calldata messageBody
) external returns (bool)
```

Handles an incoming finalized message received by the local MessageTransmitter. For a burn message, mints the associated token to the requested recipient on the local domain.

**Reference**: `src/v2/TokenMessengerV2.sol:245`

#### Parameters

* `remoteDomain` (uint32): The domain where the message originated from
* `sender` (bytes32): The sender of the message (remote TokenMessenger)
* `finalityThresholdExecuted` (uint32): The level of finality at which the message was attested (unused in finalized handler)
* `messageBody` (bytes): The message body bytes

#### Returns

* `success` (bool): True if successful

#### Requirements

* Caller must be the local MessageTransmitter
* Sender must be a registered remote TokenMessenger for the given domain

### handleReceiveUnfinalizedMessage

```solidity theme={null}
function handleReceiveUnfinalizedMessage(
    uint32 remoteDomain,
    bytes32 sender,
    uint32 finalityThresholdExecuted,
    bytes calldata messageBody
) external returns (bool)
```

Handles an incoming unfinalized message received by the local MessageTransmitter. For a burn message, mints the associated token to the requested recipient on the local domain, less fees. Fees are separately minted to the currently set `feeRecipient` address.

**Reference**: `src/v2/TokenMessengerV2.sol:274`

#### Parameters

* `remoteDomain` (uint32): The domain where the message originated from
* `sender` (bytes32): The sender of the message (remote TokenMessenger)
* `finalityThresholdExecuted` (uint32): The level of finality at which the message was attested to
* `messageBody` (bytes): The message body bytes

#### Returns

* `success` (bool): True if successful

#### Requirements

* Caller must be the local MessageTransmitter
* Sender must be a registered remote TokenMessenger for the given domain
* `finalityThresholdExecuted` must be >= `TOKEN_MESSENGER_MIN_FINALITY_THRESHOLD` (500)

## Fee Management Functions

### getMinFeeAmount

```solidity theme={null}
function getMinFeeAmount(uint256 amount) external view returns (uint256)
```

Returns the minimum fee for a given amount.

**Reference**: `src/v2/TokenMessengerV2.sol:299`

#### Parameters

* `amount` (uint256): The amount for which to calculate the minimum fee (must be > 1)

#### Returns

* Minimum fee for the given amount

#### Formula

```
minFeeAmount = (amount * minFee) / MIN_FEE_MULTIPLIER
```

Where `MIN_FEE_MULTIPLIER = 10,000,000` (enables 1/1000 basis point precision)

### setFeeRecipient

```solidity theme={null}
function setFeeRecipient(address _feeRecipient) external
```

Sets the fee recipient address (owner only).

**Reference**: `src/v2/BaseTokenMessenger.sol:222`

#### Parameters

* `_feeRecipient` (address): Address of fee recipient (cannot be zero address)

#### Events

```solidity theme={null}
event FeeRecipientSet(address feeRecipient);
```

### setMinFeeController

```solidity theme={null}
function setMinFeeController(address _minFeeController) external
```

Sets the minimum fee controller address (owner only).

**Reference**: `src/v2/BaseTokenMessenger.sol:232`

#### Parameters

* `_minFeeController` (address): Address of minimum fee controller (cannot be zero address)

#### Events

```solidity theme={null}
event MinFeeControllerSet(address minFeeController);
```

### setMinFee

```solidity theme={null}
function setMinFee(uint256 _minFee) external
```

Sets the minimum fee for all transfers in 1/1000 basis points (min fee controller only).

**Reference**: `src/v2/BaseTokenMessenger.sol:242`

#### Parameters

* `_minFee` (uint256): Minimum fee (must be \< MIN\_FEE\_MULTIPLIER)

#### Events

```solidity theme={null}
event MinFeeSet(uint256 minFee);
```

## Denylist Functions

### addToDenylist

```solidity theme={null}
function addToDenylist(address account) external
```

Adds an address to the denylist (denylister only). Denylisted addresses cannot call `depositForBurn` or `depositForBurnWithHook`.

### removeFromDenylist

```solidity theme={null}
function removeFromDenylist(address account) external
```

Removes an address from the denylist (denylister only).

## Remote TokenMessenger Management

### addRemoteTokenMessenger

```solidity theme={null}
function addRemoteTokenMessenger(
    uint32 domain,
    bytes32 tokenMessenger
) external
```

Adds a TokenMessenger for a remote domain (owner only).

**Reference**: `src/v2/BaseTokenMessenger.sol:171`

### removeRemoteTokenMessenger

```solidity theme={null}
function removeRemoteTokenMessenger(uint32 domain) external
```

Removes the TokenMessenger for a remote domain (owner only).

**Reference**: `src/v2/BaseTokenMessenger.sol:182`

## Local Minter Management

### addLocalMinter

```solidity theme={null}
function addLocalMinter(address newLocalMinter) external
```

Adds a minter for the local domain (owner only).

**Reference**: `src/v2/BaseTokenMessenger.sol:200`

### removeLocalMinter

```solidity theme={null}
function removeLocalMinter() external
```

Removes the minter for the local domain (owner only).

**Reference**: `src/v2/BaseTokenMessenger.sol:208`

## State Variables

### Immutable

* `localMessageTransmitter` (address): Local Message Transmitter address
* `messageBodyVersion` (uint32): Version of message body format

### Storage

* `localMinter` (ITokenMinterV2): Local token minter contract
* `remoteTokenMessengers` (mapping(uint32 => bytes32)): Valid TokenMessengers on remote domains
* `feeRecipient` (address): Address to receive collected fees
* `minFeeController` (address): Minimum fee controller address
* `minFee` (uint256): Minimum fee for all transfers in 1/1000 basis points
* `MIN_FEE_MULTIPLIER` (uint256): Constant value of 10,000,000 (1/1000 basis point precision)

## Integration Example

```solidity theme={null}
// Approve tokens first
usdc.approve(address(tokenMessenger), amount);

// Deposit for burn with fee and finality
tokenMessenger.depositForBurn(
    1000000, // 1 USDC (6 decimals)
    destinationDomain,
    recipientAddress,
    address(usdc),
    bytes32(0), // Any caller
    5000, // Max fee: 0.005 USDC
    1000 // Confirmed finality
);

// With hook data for custom logic
tokenMessenger.depositForBurnWithHook(
    1000000,
    destinationDomain,
    recipientAddress,
    address(usdc),
    bytes32(0),
    5000,
    1000,
    customHookData // Interpreted on destination
);
```

## Fee Calculation Example

If `minFee = 5000` (0.05%):

```
Amount: 1,000,000 (1 USDC)
minFeeAmount = (1,000,000 * 5000) / 10,000,000 = 500 (0.0005 USDC)
```

The `maxFee` parameter must be >= `minFeeAmount` and \< `amount`.

## Event Signature Changes

The V2 `DepositForBurn` event includes additional parameters compared to V1:

* `destinationCaller` (bytes32): Authorized caller specification
* `maxFee` (uint256): Maximum fee willing to pay
* `minFinalityThreshold` (uint32): Minimum finality requirement (indexed)
* `hookData` (bytes): Optional hook data

## Security Considerations

1. **Fee Validation**: Max fee is validated to be less than amount and meet minimum fee requirements
2. **Denylist Protection**: Denylisted addresses cannot initiate burns
3. **Caller Authorization**: Optional destination caller restriction
4. **Finality Thresholds**: Minimum finality of 500 required for unfinalized messages
5. **Message Expiration**: Burn messages can include expiration blocks
