Skip to main content

Overview

TokenMinterV2 is responsible for minting and burning tokens on the local domain. It inherits from the V1 TokenMinter contract and adds support for minting to multiple recipients in a single transaction, enabling efficient fee distribution. Contract Location: src/v2/TokenMinterV2.sol

Key Features

New Features vs V1

  1. Multi-Recipient Minting: Mint to two recipients in a single transaction (useful for separating fees)
  2. Efficient Fee Distribution: Mint principal amount to recipient and fee to fee recipient atomically
  3. Backward Compatible: Inherits all V1 functionality for single-recipient minting

Constructor

constructor(address _tokenController)

Parameters

  • _tokenController (address): Token controller address

Core Functions

mint (Multi-Recipient)

function mint(
    uint32 sourceDomain,
    bytes32 burnToken,
    address recipientOne,
    address recipientTwo,
    uint256 amountOne,
    uint256 amountTwo
) external returns (address)
Mints to multiple recipients amounts of local tokens corresponding to the given (sourceDomain, burnToken) pair. Reference: src/v2/TokenMinterV2.sol:54

Parameters

  • sourceDomain (uint32): Source domain where burnToken was burned
  • burnToken (bytes32): Burned token address as bytes32
  • recipientOne (address): Address to receive amountOne of minted tokens
  • recipientTwo (address): Address to receive amountTwo of minted tokens
  • amountOne (uint256): Amount of tokens to mint to recipientOne
  • amountTwo (uint256): Amount of tokens to mint to recipientTwo

Returns

  • mintToken (address): Address of the token that was minted

Requirements

  • Contract must not be paused
  • Caller must be the local TokenMessenger
  • The (sourceDomain, burnToken) pair must map to a nonzero local token address
  • Both mint operations must succeed

Behavior

This function performs two sequential mint operations:
  1. Mints amountOne to recipientOne
  2. Mints amountTwo to recipientTwo
If either mint operation fails, the entire transaction reverts.

Inherited Functions

From TokenMinter (V1):

mint (Single-Recipient)

function mint(
    uint32 sourceDomain,
    bytes32 burnToken,
    address to,
    uint256 amount
) external returns (address mintToken)
Mints amount of local tokens corresponding to the given (sourceDomain, burnToken) pair, to to address. Reference: src/TokenMinter.sol:85

Parameters

  • sourceDomain (uint32): Source domain where burnToken was burned
  • burnToken (bytes32): Burned token address as bytes32
  • to (address): Address to receive minted tokens
  • amount (uint256): Amount of tokens to mint

Returns

  • mintToken (address): Token that was minted

burn

function burn(address burnToken, uint256 burnAmount) external
Burns tokens owned by this TokenMinter. Reference: src/TokenMinter.sol:111

Parameters

  • burnToken (address): Burnable token address
  • burnAmount (uint256): Amount of tokens to burn (must be greater than 0 and less than or equal to maximum burn amount per message)

Requirements

  • Contract must not be paused
  • Caller must be the local TokenMessenger
  • Burn amount must be within the burn limit for the token

Token Controller Functions

linkTokenPair

function linkTokenPair(
    address localToken,
    uint32 remoteDomain,
    bytes32 remoteToken
) external
Links a local token to a remote token (token controller only).

unlinkTokenPair

function unlinkTokenPair(
    address localToken,
    uint32 remoteDomain,
    bytes32 remoteToken
) external
Unlinks a local token from a remote token (token controller only).

setMaxBurnAmountPerMessage

function setMaxBurnAmountPerMessage(
    address localToken,
    uint256 burnLimitPerMessage
) external
Sets the maximum burn amount per message for a local token (token controller only).

getLocalToken

function getLocalToken(
    uint32 remoteDomain,
    bytes32 remoteToken
) external view returns (address)
Gets the local token address associated with the given remote domain and token.

Local TokenMessenger Management

addLocalTokenMessenger

function addLocalTokenMessenger(address newLocalTokenMessenger) external
Adds a TokenMessenger for the local domain (owner only). Only this TokenMessenger has permission to call mint() and burn() on this TokenMinter. Reference: src/TokenMinter.sol:128

removeLocalTokenMessenger

function removeLocalTokenMessenger() external
Removes the TokenMessenger for the local domain (owner only). Reference: src/TokenMinter.sol:151

setTokenController

function setTokenController(address newTokenController) external
Sets the token controller address (owner only). Reference: src/TokenMinter.sol:168

State Variables

Inherited from TokenMinter

  • localTokenMessenger (address): Local TokenMessenger with permission to call mint and burn
  • tokenController (address): Token controller address (inherited from TokenController)

Inherited from TokenController

  • burnLimitsPerMessage (mapping): Per-token burn limits
  • remoteTokensToLocalTokens (mapping): Remote token to local token mappings

Integration Example

Multi-Recipient Mint (V2)

// TokenMessenger calls TokenMinter to mint tokens and fees
address mintedToken = tokenMinter.mint(
    sourceDomain,
    burnToken,
    recipient,      // Main recipient
    feeRecipient,   // Fee recipient
    950000,         // 0.95 USDC to recipient
    50000           // 0.05 USDC fee to fee recipient
);

Single-Recipient Mint (V1 Compatibility)

// Traditional single-recipient mint
address mintedToken = tokenMinter.mint(
    sourceDomain,
    burnToken,
    recipient,
    1000000 // Full 1 USDC to recipient
);

Burn Tokens

// TokenMessenger calls TokenMinter to burn tokens
tokenMinter.burn(
    address(usdc),
    1000000 // 1 USDC
);

Differences from V1

| Feature | V1 | V2 | |---------|----|----|| | Single-recipient mint | ✓ | ✓ (inherited) | | Multi-recipient mint | ✗ | ✓ | | Burn functionality | ✓ | ✓ (inherited) | | Token controller | ✓ | ✓ (inherited) | | Burn limits | ✓ | ✓ (inherited) |

Multi-Recipient Use Cases

  1. Fee Distribution: Mint principal to recipient and fee to protocol in one transaction
  2. Gas Optimization: Reduce gas costs by combining multiple mints
  3. Atomic Operations: Ensure both mints succeed or both fail
  4. Simplified Logic: Remove need for TokenMessenger to call mint twice

Function Signatures

V2 Multi-Recipient Mint

mint(uint32,bytes32,address,address,uint256,uint256)

V1 Single-Recipient Mint

mint(uint32,bytes32,address,uint256)
Both functions have the same name but different signatures, allowing the TokenMessenger to choose which to call based on whether fees need to be distributed.

Security Considerations

  1. Burn Limit Controls: Enhanced burn limit enforcement prevents excessive burns per message
  2. Permission System: Only the registered local TokenMessenger can mint or burn
  3. Token Pairing: Strict token pairing validation ensures correct cross-chain token mappings
  4. Atomic Minting: Multi-recipient minting is atomic - both mints succeed or both fail
  5. Access Control: Token controller, owner, and pauser roles enforce proper authorization

Build docs developers (and LLMs) love