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

# ITokenMinter

> Interface for minting and burning tokens in cross-chain transfers

## Overview

The `ITokenMinter` interface defines the contract for managing tokens that are mintable, burnable, and transferable across domains. This interface is central to CCTP's token transfer mechanism, handling the burn on source chains and mint on destination chains.

## Interface Definition

### ITokenMinter (V1)

```solidity theme={null}
interface ITokenMinter {
    function mint(
        uint32 sourceDomain,
        bytes32 burnToken,
        address to,
        uint256 amount
    ) external returns (address mintToken);

    function burn(address burnToken, uint256 amount) external;

    function getLocalToken(uint32 remoteDomain, bytes32 remoteToken)
        external
        view
        returns (address);

    function setTokenController(address newTokenController) external;
}
```

**Source:** `src/interfaces/ITokenMinter.sol:23`

### ITokenMinterV2

V2 extends the base interface with multi-recipient minting:

```solidity theme={null}
interface ITokenMinterV2 is ITokenMinter {
    function mint(
        uint32 sourceDomain,
        bytes32 burnToken,
        address recipientOne,
        address recipientTwo,
        uint256 amountOne,
        uint256 amountTwo
    ) external returns (address);
}
```

**Source:** `src/interfaces/v2/ITokenMinterV2.sol:27`

## Functions

### mint

```solidity theme={null}
function mint(
    uint32 sourceDomain,
    bytes32 burnToken,
    address to,
    uint256 amount
) external returns (address mintToken);
```

Mints local tokens corresponding to tokens burned on the source domain.

**Parameters:**

* `sourceDomain` - The domain ID where the tokens were burned
* `burnToken` - The address of the burned token on the source domain (as bytes32)
* `to` - The address to receive the minted tokens on this domain
* `amount` - The amount of tokens to mint

**Returns:**

* `mintToken` - The address of the token contract that was minted

**Reverts if:**

* The (`sourceDomain`, `burnToken`) pair does not map to a valid local token
* The amount exceeds the minter's allowance for the token
* The mint operation fails

### burn

```solidity theme={null}
function burn(address burnToken, uint256 amount) external;
```

Burns tokens owned by the TokenMinter contract.

**Parameters:**

* `burnToken` - The address of the token contract to burn from
* `amount` - The amount of tokens to burn

**Reverts if:**

* The amount exceeds the TokenMinter's balance of the token
* The burn operation fails

### getLocalToken

```solidity theme={null}
function getLocalToken(uint32 remoteDomain, bytes32 remoteToken)
    external
    view
    returns (address);
```

Queries the local token address corresponding to a remote domain and token.

**Parameters:**

* `remoteDomain` - The remote domain ID
* `remoteToken` - The token address on the remote domain (as bytes32)

**Returns:**

* The local token address, or address(0) if no mapping exists

### setTokenController

```solidity theme={null}
function setTokenController(address newTokenController) external;
```

Sets the token controller responsible for managing token mappings and limits.

**Parameters:**

* `newTokenController` - The address of the new token controller

## Token Management

### Token Mappings

The TokenMinter maintains bidirectional mappings between local and remote tokens:

```solidity theme={null}
// Query local token for a remote token
address localUSDC = tokenMinter.getLocalToken(
    0,  // Ethereum domain
    0x000000000000000000000000A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48  // USDC on Ethereum
);
```

### Minter Allowances

Each token has a per-minter allowance that limits the amount that can be minted:

* Prevents unlimited minting even if the minter is compromised
* Set by the token controller based on liquidity and risk parameters
* Must be sufficient to cover the mint amount

### Token Controller

The token controller is responsible for:

* Mapping local tokens to remote tokens across domains
* Setting and managing per-minter allowances
* Configuring token-specific transfer limits
* Managing token-related permissions

## V2 Enhancements

### Multi-Recipient Minting

V2 introduces the ability to mint to multiple recipients in a single operation:

```solidity theme={null}
function mint(
    uint32 sourceDomain,
    bytes32 burnToken,
    address recipientOne,
    address recipientTwo,
    uint256 amountOne,
    uint256 amountTwo
) external returns (address);
```

**Parameters:**

* `sourceDomain` - The domain where tokens were burned
* `burnToken` - The burned token address (as bytes32)
* `recipientOne` - First recipient address
* `recipientTwo` - Second recipient address
* `amountOne` - Amount to mint to first recipient
* `amountTwo` - Amount to mint to second recipient

**Returns:**

* The address of the minted token contract

**Use Cases:**

* Fee splitting between recipient and relayer
* Atomic distribution to multiple parties
* Gas-efficient multi-party settlements

**Example:**

```solidity theme={null}
// Mint 95 USDC to user and 5 USDC to relayer as fee
address mintedToken = tokenMinterV2.mint(
    0,              // Source domain (Ethereum)
    usdcBytes32,    // Burned USDC address
    userAddress,    // 95% recipient
    relayerAddress, // 5% fee recipient
    95e6,          // 95 USDC (6 decimals)
    5e6            // 5 USDC relayer fee
);
```

## Usage in CCTP Flow

### Burn Flow (Source Chain)

1. User approves TokenMessenger to spend tokens
2. TokenMessenger transfers tokens to TokenMinter
3. TokenMinter burns the tokens:
   ```solidity theme={null}
   // In TokenMessenger.depositForBurn
   _mintBurnToken.transferFrom(msg.sender, address(_localMinter), amount);
   _localMinter.burn(_burnToken, amount);
   ```

**Source:** `src/TokenMessenger.sol:444`

### Mint Flow (Destination Chain)

1. MessageReceiver validates and forwards message to TokenMessenger
2. TokenMessenger calls TokenMinter to mint tokens:
   ```solidity theme={null}
   // In TokenMessenger.handleReceiveMessage
   ITokenMinter _localMinter = _getLocalMinter();
   address _mintToken = _minter.mint(
       remoteDomain,
       _burnToken,
       _mintRecipient,
       _amount
   );
   ```

**Source:** `src/TokenMessenger.sol:534`

## Implementation Requirements

### Security Considerations

1. **Access Control** - Only authorized contracts (e.g., TokenMessenger) should call mint/burn
2. **Token Validation** - Verify token mappings exist before minting
3. **Allowance Checks** - Ensure mint amounts don't exceed minter allowances
4. **Balance Verification** - Confirm sufficient balance before burning

### Example Implementation Pattern

```solidity theme={null}
contract TokenMinter is ITokenMinter, Ownable {
    // Token mappings: domain => remote token => local token
    mapping(uint32 => mapping(bytes32 => address)) public remoteTokensToLocalTokens;
    
    // Minter allowances: token => minter => allowance
    mapping(address => mapping(address => uint256)) public minterAllowance;
    
    address public tokenController;
    
    function mint(
        uint32 sourceDomain,
        bytes32 burnToken,
        address to,
        uint256 amount
    ) external returns (address mintToken) {
        // Get local token for the remote token
        mintToken = getLocalToken(sourceDomain, burnToken);
        require(mintToken != address(0), "Invalid token pair");
        
        // Check minter allowance
        require(
            minterAllowance[mintToken][msg.sender] >= amount,
            "Exceeds minter allowance"
        );
        
        // Decrease allowance
        minterAllowance[mintToken][msg.sender] -= amount;
        
        // Mint tokens to recipient
        IMintBurnToken(mintToken).mint(to, amount);
        
        return mintToken;
    }
    
    function burn(address burnToken, uint256 amount) external {
        require(amount > 0, "Amount must be nonzero");
        
        // Burn tokens from this contract's balance
        IMintBurnToken(burnToken).burn(amount);
    }
    
    function getLocalToken(uint32 remoteDomain, bytes32 remoteToken)
        external
        view
        returns (address)
    {
        return remoteTokensToLocalTokens[remoteDomain][remoteToken];
    }
    
    function setTokenController(address newTokenController) external onlyOwner {
        require(newTokenController != address(0), "Invalid controller");
        tokenController = newTokenController;
    }
}
```

## Related Interfaces

* [IMessageHandler](/api/interfaces/message-handler) - Handles messages that trigger mint operations
* [IMintBurnToken](/api/token-minter) - Token contract interface for mint/burn operations
* [TokenMessenger](/api/token-messenger) - Primary user of ITokenMinter interface
