CCTPBridgeAdapter
Inherits: ICCTPBridgeAdapter
Title: CCTPBridgeAdapter
Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from Circle CCTP v2 (https://github.com/circlefin/evm-cctp-contracts)
Circle CCTP v2 USDC token-bridge facet: depositForBurn burns USDC on this chain toward an
ERC-7930 recipient, relayMessage forwards an Iris-attested inbound message to the CCTP
transmitter for minting. CCTP is a TOKEN BRIDGE (burn-and-mint), NOT an ERC-7786 message gateway —
this facet is deliberately not an IERC7786GatewaySource and never routes through OpenBridge.
Stateless delegator — logic/storage live in CCTPBridgeAdapterLib. The outbound burn is nonReentrant
with strict CEI and exact-amount approval hygiene; the inbound relay is a PERMISSIONLESS passthrough
(trust roots in Circle's Iris attester set + denylist, not this contract), except that relayMessage
refuses a Lattice hooked burn from anyone but its mintRecipient so the hook cannot be skipped. A Lattice
hooked burn requires the destination domain's destinationCaller to be the destination diamond.
Notes:
- lattice-version: 0.1.0
- lattice-source: Circle
Functions
depositForBurn
Burns amount USDC (pulled from msg.sender) for minting to the ERC-7930 recipient on its
destination chain via CCTP. Approves the TokenMessenger for EXACTLY amount, then resets to 0.
function depositForBurn(uint256 amount, bytes calldata recipient) external virtual;Parameters
| Name | Type | Description |
|---|---|---|
| amount | uint256 | |
| recipient | bytes |
depositForBurnWithHook
Like depositForBurn but attaches CCTP v2 hookData to the burn message (via
TokenMessengerV2.depositForBurnWithHook) for the destination recipient to execute. Reverts
CCTPEmptyHookData if hookData is empty (use depositForBurn for a hook-less burn). When
hookData is a Lattice envelope (HOOK_MAGIC ‖ target ‖ payload) it also reverts
CCTPHookWithoutDestinationCaller unless the destination domain's destinationCaller is set: it
MUST be the destination diamond, or anyone could mint via Circle's transmitter and skip the hook.
Other hookData is not guarded (the destination relays it plainly). The lock is PER DOMAIN, so it
also routes plain depositForBurn burns to that domain through the destination diamond.
function depositForBurnWithHook(uint256 amount, bytes calldata recipient, bytes calldata hookData)
external
virtual;Parameters
| Name | Type | Description |
|---|---|---|
| amount | uint256 | |
| recipient | bytes | |
| hookData | bytes |
relayMessage
PERMISSIONLESS passthrough: forwards an Iris-attested CCTP message to the transmitter, which
mints USDC directly to the recipient. Reverts CCTPRelayFailed if the transmitter returns false.
A burn carrying a valid Lattice hook envelope (one relayMessageWithHook accepts) reverts
CCTPHookRelayRequired BEFORE minting unless the caller is its attested mintRecipient (an
escape hatch that delivers the funds without running the hook).
function relayMessage(bytes calldata message, bytes calldata attestation) external virtual;Parameters
| Name | Type | Description |
|---|---|---|
| message | bytes | |
| attestation | bytes |
relayMessageWithHook
PERMISSIONLESS relay that ALSO executes a Lattice hook envelope carried in the burn message: it
validates the message is a BurnMessageV2 addressed to this adapter's TokenMessenger carrying a
valid Lattice hookData envelope, mints via the transmitter, THEN calls the decoded hook target
through the CCTPHookExecutor with Circle-ATTESTED context. Hook execution is LENIENT — a
reverting/return-bombing target does NOT revert the relay (the mint stands, nonce consumed) —
but a target whose OWN frame runs out of gas reverts the whole relay with
ICCTPHookExecutor.CCTPHookOutOfGas, leaving the nonce live for a retry with more gas. A sub-call
out-of-gas reads as an ordinary revert unless the target re-raises it (ICCTPHookReceiver).
Reverts CCTPNotBurnMessage / CCTPInvalidHookData on a non-conforming message BEFORE minting,
and CCTPRelayFailed if the transmitter returns false.
function relayMessageWithHook(bytes calldata message, bytes calldata attestation) external virtual;Parameters
| Name | Type | Description |
|---|---|---|
| message | bytes | |
| attestation | bytes |
registerChainDomain
Registers chainId ⇒ CCTP domain. Admin only. Verify the domain table at deploy.
function registerChainDomain(uint256 chainId, uint32 domain) external virtual;Parameters
| Name | Type | Description |
|---|---|---|
| chainId | uint256 | |
| domain | uint32 |
configureDomain
Sets the per-domain maxFee, minFinalityThreshold and destinationCaller. Admin only.
function configureDomain(uint32 domain, uint256 maxFee, uint32 minFinalityThreshold, bytes32 destinationCaller)
external
virtual;Parameters
| Name | Type | Description |
|---|---|---|
| domain | uint32 | |
| maxFee | uint256 | |
| minFinalityThreshold | uint32 | |
| destinationCaller | bytes32 |
tokenMessenger
The CCTP v2 TokenMessengerV2 this adapter burns through.
function tokenMessenger() external view virtual returns (address);Returns
| Name | Type | Description |
|---|---|---|
| <none> | address |
messageTransmitter
The CCTP v2 MessageTransmitterV2 this adapter relays inbound messages to.
function messageTransmitter() external view virtual returns (address);Returns
| Name | Type | Description |
|---|---|---|
| <none> | address |
usdc
The bridged USDC token (burn source of funds is msg.sender, not the Diamond balance).
function usdc() external view virtual returns (address);Returns
| Name | Type | Description |
|---|---|---|
| <none> | address |
getDomain
The CCTP domain registered for chainId (meaningless unless isChainRegistered is true).
function getDomain(uint256 chainId) external view virtual returns (uint32);Parameters
| Name | Type | Description |
|---|---|---|
| chainId | uint256 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint32 |
domainOwner
The chainId that registered domain (0 = unregistered).
function domainOwner(uint32 domain) external view virtual returns (uint256);Parameters
| Name | Type | Description |
|---|---|---|
| domain | uint32 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint256 |
isChainRegistered
Whether chainId has a registered CCTP domain (distinguishes domain 0 = Ethereum from unset).
function isChainRegistered(uint256 chainId) external view virtual returns (bool);Parameters
| Name | Type | Description |
|---|---|---|
| chainId | uint256 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
getDomainConfig
The per-domain config used when burning toward domain.
function getDomainConfig(uint32 domain)
external
view
virtual
returns (uint256 maxFee, uint32 minFinalityThreshold, bytes32 destinationCaller);Parameters
| Name | Type | Description |
|---|---|---|
| domain | uint32 |
Returns
| Name | Type | Description |
|---|---|---|
| maxFee | uint256 | |
| minFinalityThreshold | uint32 | |
| destinationCaller | bytes32 |
hookExecutor
The role-less, fund-less CCTPHookExecutor this diamond routes inbound hooks through (deployed once at init, immutable — no setter). Never the zero address on an initialized adapter.
function hookExecutor() external view virtual returns (address);Returns
| Name | Type | Description |
|---|---|---|
| <none> | address |
exportSelectors
ERC-8153 selector export: this facet's cuttable selectors, tightly packed (4 bytes each).
Excludes exportSelectors() itself (0x0ef22643) - it is never cut into a diamond. Order matches
forge inspect CCTPBridgeAdapter methodIdentifiers (alphabetical by signature); kept in exact parity by
ExportSelectorsParityTest. Chunks:
configureDomain(uint32,uint256,uint32,bytes32) 0x4736cc95
depositForBurn(uint256,bytes) 0x3d8f1160
depositForBurnWithHook(uint256,bytes,bytes) 0x14385403
domainOwner(uint32) 0x3f1f7a9f
getDomain(uint256) 0x1a7a98e2
getDomainConfig(uint32) 0xf7d38221
hookExecutor() 0xef21b76f
isChainRegistered(uint256) 0xb9e06402
messageTransmitter() 0x7b04c181
registerChainDomain(uint256,uint32) 0xa3e6f535
relayMessage(bytes,bytes) 0x29351b45
relayMessageWithHook(bytes,bytes) 0x96692d34
tokenMessenger() 0x46117830
usdc() 0x3e413bee
function exportSelectors() external pure virtual returns (bytes memory selectors);Returns
| Name | Type | Description |
|---|---|---|
| selectors | bytes |