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

# TokenMessenger

> Contract responsible for facilitating cross-chain token transfers via deposit and burn

## Overview

The `TokenMessenger` contract serves as the primary interface for users to burn tokens on the source chain and mint them on the destination chain. It integrates with both the `MessageTransmitter` for cross-chain messaging and the `TokenMinter` for token minting and burning operations.

## State Variables

<ParamField path="localMessageTransmitter" type="IMessageTransmitter" required>
  Local Message Transmitter responsible for sending and receiving messages to/from remote domains. This is an immutable reference set during contract deployment.
</ParamField>

<ParamField path="messageBodyVersion" type="uint32" required>
  Version of message body format. This immutable value defines the structure of burn messages.
</ParamField>

<ParamField path="localMinter" type="ITokenMinter" required>
  Minter responsible for minting and burning tokens on the local domain.
</ParamField>

<ParamField path="remoteTokenMessengers" type="mapping(uint32 => bytes32)" required>
  Mapping of domain to valid TokenMessenger addresses on remote domains.
</ParamField>

## Functions

### depositForBurn

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

```solidity theme={null}
function depositForBurn(
    uint256 amount,
    uint32 destinationDomain,
    bytes32 mintRecipient,
    address burnToken
) external returns (uint64 _nonce)
```

<ParamField path="amount" type="uint256" required>
  Amount of tokens to burn. Must be greater than 0.
</ParamField>

<ParamField path="destinationDomain" type="uint32" required>
  Destination domain where tokens will be minted
</ParamField>

<ParamField path="mintRecipient" type="bytes32" required>
  Address of mint recipient on destination domain as bytes32. Must be nonzero.
</ParamField>

<ParamField path="burnToken" type="address" required>
  Address of contract to burn deposited tokens on local domain
</ParamField>

**Returns:** `uint64` - Unique nonce reserved by the message

**Behavior:**

* Transfers tokens from sender to the TokenMinter contract
* Burns the tokens via the TokenMinter
* Formats a burn message with token and recipient details
* Sends the message via MessageTransmitter
* Emits a `DepositForBurn` event
* Any address can call `receiveMessage()` on the destination domain

**Reverts if:**

* Amount is 0
* Mint recipient is bytes32(0)
* Given burnToken is not supported
* Given destinationDomain has no TokenMessenger registered
* transferFrom() fails (e.g., insufficient balance or allowance)
* burn() fails
* MessageTransmitter returns false or reverts

### depositForBurnWithCaller

Deposits and burns tokens from sender to be minted on the destination domain. The mint on the destination domain must be called by the specified `destinationCaller`.

```solidity theme={null}
function depositForBurnWithCaller(
    uint256 amount,
    uint32 destinationDomain,
    bytes32 mintRecipient,
    address burnToken,
    bytes32 destinationCaller
) external returns (uint64 nonce)
```

<ParamField path="amount" type="uint256" required>
  Amount of tokens to burn
</ParamField>

<ParamField path="destinationDomain" type="uint32" required>
  Destination domain
</ParamField>

<ParamField path="mintRecipient" type="bytes32" required>
  Address of mint recipient on destination domain
</ParamField>

<ParamField path="burnToken" type="address" required>
  Address of contract to burn deposited tokens on local domain
</ParamField>

<ParamField path="destinationCaller" type="bytes32" required>
  Caller on the destination domain, as bytes32. Must be nonzero.
</ParamField>

**Returns:** `uint64` - Unique nonce reserved by message

<Warning>
  If the `destinationCaller` does not represent a valid address as bytes32, it will not be possible to broadcast the message on the destination domain. This is an advanced feature - the standard `depositForBurn()` should be preferred for most use cases.
</Warning>

### handleReceiveMessage

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

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

<ParamField path="remoteDomain" type="uint32" required>
  The domain where the message originated from
</ParamField>

<ParamField path="sender" type="bytes32" required>
  The sender of the message (remote TokenMessenger)
</ParamField>

<ParamField path="messageBody" type="bytes" required>
  The message body bytes containing burn message details
</ParamField>

**Returns:** `bool` - true if successful

**Validation:**

* Validates the local sender is the local MessageTransmitter
* Validates the remote sender is a registered remote TokenMessenger for `remoteDomain`
* Validates burn message format
* Validates message body version

**Behavior:**

* Extracts mint recipient, burn token, and amount from message body
* Calls the TokenMinter to mint tokens to the recipient
* Emits a `MintAndWithdraw` event

### replaceDepositForBurn

Replaces a BurnMessage to change the mint recipient and/or destination caller. Allows the sender of a previous BurnMessage to send a new message to replace the original.

```solidity theme={null}
function replaceDepositForBurn(
    bytes calldata originalMessage,
    bytes calldata originalAttestation,
    bytes32 newDestinationCaller,
    bytes32 newMintRecipient
) external
```

<ParamField path="originalMessage" type="bytes" required>
  Original message bytes to replace
</ParamField>

<ParamField path="originalAttestation" type="bytes" required>
  Original attestation bytes. Must be a valid attestation of `originalMessage`.
</ParamField>

<ParamField path="newDestinationCaller" type="bytes32" required>
  The new destination caller, which may be the same as the original destination caller, a new destination caller, or an empty destination caller (bytes32(0), indicating that any destination caller is valid)
</ParamField>

<ParamField path="newMintRecipient" type="bytes32" required>
  The new mint recipient, which may be the same as the original mint recipient or different. Must be nonzero.
</ParamField>

**Behavior:**

* Validates message format and attestation
* Verifies msg.sender matches the sender of the original message
* Reuses the original message's amount and burn token
* Does not require a new deposit
* Emits a new `DepositForBurn` event

<Note>
  The new message will reuse the original message's nonce. For a given nonce, all replacement message(s) and the original message are valid to broadcast on the destination domain, until the first message at the nonce confirms, at which point all others are invalidated.
</Note>

### addRemoteTokenMessenger

Adds a TokenMessenger for a remote domain. Only callable by the contract owner.

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

<ParamField path="domain" type="uint32" required>
  Domain of remote TokenMessenger
</ParamField>

<ParamField path="tokenMessenger" type="bytes32" required>
  Address of remote TokenMessenger as bytes32. Must be nonzero.
</ParamField>

**Reverts if:**

* tokenMessenger is bytes32(0)
* A TokenMessenger is already set for the domain

### removeRemoteTokenMessenger

Removes the TokenMessenger for a remote domain. Only callable by the contract owner.

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

<ParamField path="domain" type="uint32" required>
  Domain of remote TokenMessenger to remove
</ParamField>

**Reverts if:**

* No TokenMessenger is set for the given remote domain

### addLocalMinter

Adds a minter for the local domain. Only callable by the contract owner.

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

<ParamField path="newLocalMinter" type="address" required>
  The address of the minter on the local domain. Must be nonzero.
</ParamField>

**Reverts if:**

* newLocalMinter is address(0)
* A local minter is already set

### removeLocalMinter

Removes the minter for the local domain. Only callable by the contract owner.

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

**Reverts if:**

* No local minter is set

## Events

### DepositForBurn

Emitted when a DepositForBurn message is sent.

```solidity theme={null}
event DepositForBurn(
    uint64 indexed nonce,
    address indexed burnToken,
    uint256 amount,
    address indexed depositor,
    bytes32 mintRecipient,
    uint32 destinationDomain,
    bytes32 destinationTokenMessenger,
    bytes32 destinationCaller
)
```

<ParamField path="nonce" type="uint64" indexed>
  Unique nonce reserved by message
</ParamField>

<ParamField path="burnToken" type="address" indexed>
  Address of token burnt on source domain
</ParamField>

<ParamField path="amount" type="uint256">
  Deposit amount
</ParamField>

<ParamField path="depositor" type="address" indexed>
  Address where deposit is transferred from
</ParamField>

<ParamField path="mintRecipient" type="bytes32">
  Address receiving minted tokens on destination domain as bytes32
</ParamField>

<ParamField path="destinationDomain" type="uint32">
  Destination domain
</ParamField>

<ParamField path="destinationTokenMessenger" type="bytes32">
  Address of TokenMessenger on destination domain as bytes32
</ParamField>

<ParamField path="destinationCaller" type="bytes32">
  Authorized caller as bytes32 of receiveMessage() on destination domain. If equal to bytes32(0), any address can call receiveMessage().
</ParamField>

### MintAndWithdraw

Emitted when tokens are minted on the destination domain.

```solidity theme={null}
event MintAndWithdraw(
    address indexed mintRecipient,
    uint256 amount,
    address indexed mintToken
)
```

<ParamField path="mintRecipient" type="address" indexed>
  Recipient address of minted tokens
</ParamField>

<ParamField path="amount" type="uint256">
  Amount of minted tokens
</ParamField>

<ParamField path="mintToken" type="address" indexed>
  Contract address of minted token
</ParamField>

### RemoteTokenMessengerAdded

Emitted when a remote TokenMessenger is added.

```solidity theme={null}
event RemoteTokenMessengerAdded(uint32 domain, bytes32 tokenMessenger)
```

### RemoteTokenMessengerRemoved

Emitted when a remote TokenMessenger is removed.

```solidity theme={null}
event RemoteTokenMessengerRemoved(uint32 domain, bytes32 tokenMessenger)
```

### LocalMinterAdded

Emitted when the local minter is added.

```solidity theme={null}
event LocalMinterAdded(address localMinter)
```

### LocalMinterRemoved

Emitted when the local minter is removed.

```solidity theme={null}
event LocalMinterRemoved(address localMinter)
```

## Integration

The TokenMessenger integrates with two key contracts:

### MessageTransmitter Integration

* Uses `sendMessage()` or `sendMessageWithCaller()` to send burn messages cross-chain
* Uses `replaceMessage()` to replace existing burn messages
* Implements `IMessageHandler` interface to receive messages via `handleReceiveMessage()`

### TokenMinter Integration

* Calls `burn()` to burn tokens on the source chain
* Calls `mint()` to mint tokens on the destination chain
* Manages the relationship with the local TokenMinter instance
