Overview
MessageTransmitterV2 is the core contract responsible for sending and receiving cross-chain messages in CCTP V2. It inherits from BaseMessageTransmitter and introduces finality threshold functionality, allowing messages to be attested at different levels of finality.
Contract Location: src/v2/MessageTransmitterV2.sol
Key Features
New Features vs V1
- Finality Thresholds: Messages can specify minimum finality requirements and are attested at specific finality levels
- Destination Caller: Messages can specify an authorized caller on the destination domain
- Enhanced Message Format: V2 message format includes
minFinalityThresholdandfinalityThresholdExecutedfields - Dual Message Handlers: Separate handling for finalized vs unfinalized messages
Finality Threshold Levels
- FINALITY_THRESHOLD_FINALIZED (
2000): Messages at or above this threshold are considered finalized - FINALITY_THRESHOLD_CONFIRMED (
1000): Messages at or above this threshold are considered confirmed - TOKEN_MESSENGER_MIN_FINALITY_THRESHOLD (
500): Minimum threshold accepted by TokenMessenger
Constructor
Parameters
_localDomain(uint32): Domain of the chain on which the contract is deployed_version(uint32): Message format version
Initialization
Parameters
owner_(address): Owner address (cannot be zero address)pauser_(address): Pauser addressrescuer_(address): Rescuer addressattesterManager_(address): AttesterManager address (cannot be zero address)attesters_(address[]): Set of attesters to enablesignatureThreshold_(uint256): Signature threshold (must not exceed number of attesters)maxMessageBodySize_(uint256): Maximum message body size (must be greater than zero)
Requirements
- Owner and attester manager must be non-zero addresses
- Signature threshold must not exceed the number of enabled attesters
- Max message body size must be greater than zero
Core Functions
sendMessage
src/v2/MessageTransmitterV2.sol:143
Parameters
destinationDomain(uint32): Domain of destination chainrecipient(bytes32): Address of message recipient on destination chain as bytes32destinationCaller(bytes32): Authorized caller on the destination domain as bytes32. If equal tobytes32(0), any address can broadcast the messageminFinalityThreshold(uint32): The minimum finality level at which the message should be attested tomessageBody(bytes): Contents of the message
Requirements
- Contract must not be paused
- Destination domain cannot be the local domain
- Message body length must not exceed
maxMessageBodySize - Recipient must be nonzero
Events
receiveMessage
src/v2/MessageTransmitterV2.sol:206
Parameters
message(bytes): Message bytesattestation(bytes): Concatenated 65-byte signature(s) of the message, in increasing order of the attester address recovered from signatures
Returns
success(bool): True if successful
Message Format
| Field | Bytes | Type | Index |
|---|---|---|---|
| version | 4 | uint32 | 0 |
| sourceDomain | 4 | uint32 | 4 |
| destinationDomain | 4 | uint32 | 8 |
| nonce | 32 | bytes32 | 12 |
| sender | 32 | bytes32 | 44 |
| recipient | 32 | bytes32 | 76 |
| destinationCaller | 32 | bytes32 | 108 |
| minFinalityThreshold | 4 | uint32 | 140 |
| finalityThresholdExecuted | 4 | uint32 | 144 |
| messageBody | dynamic | bytes | 148 |
Attestation Format
A valid attestation is the concatenated 65-byte signature(s) of exactlysignatureThreshold signatures, in increasing order of attester address.
Important: If the attester addresses recovered from signatures are not in increasing order, signature verification will fail. Duplicate signatures will also cause verification to fail.
Requirements
- Contract must not be paused
- Message must pass attestation signature verification
- Destination domain must match local domain
- If destination caller is specified, it must match
msg.sender - Message version must match contract version
- Nonce must not have been used previously
Behavior
Depending on thefinalityThresholdExecuted value:
- If
finalityThresholdExecuted < FINALITY_THRESHOLD_FINALIZED: CallshandleReceiveUnfinalizedMessage()on the recipient - If
finalityThresholdExecuted >= FINALITY_THRESHOLD_FINALIZED: CallshandleReceiveFinalizedMessage()on the recipient
Events
Inherited Functions
FromBaseMessageTransmitter:
- setMaxMessageBodySize(): Sets the maximum message body size (owner only)
- pause(): Pauses the contract (pauser only)
- unpause(): Unpauses the contract (pauser only)
- updatePauser(): Updates the pauser address (owner only)
- updateRescuer(): Updates the rescuer address (owner only)
- enableAttester(): Enables an attester (attester manager only)
- disableAttester(): Disables an attester (attester manager only)
- setSignatureThreshold(): Sets the signature threshold (attester manager only)
State Variables
Immutable
localDomain(uint32): Domain of the chain on which the contract is deployedversion(uint32): Message format version
Storage
maxMessageBodySize(uint256): Maximum size of message body in bytesusedNonces(mapping(bytes32 => uint256)): Mapping of nonce to usage status (0 = unused, 1 = used)
Integration Example
Security Considerations
- Nonce Replay Protection: Each nonce can only be used once
- Attestation Verification: Signatures must be in increasing order by attester address
- Domain Validation: Messages can only be sent to domains different from the local domain
- Caller Authorization: Optional destination caller restriction for enhanced security
- Finality Requirements: Minimum finality thresholds ensure appropriate security levels