Skip to content
Lattice

L2ToL2CrossDomainMessengerGatewayAdapterLib

Git Source

Title: L2ToL2CrossDomainMessengerGatewayAdapterLib

Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from Optimism (https://github.com/ethereum-optimism/optimism)

Logic + ERC-7201 storage for the OP Superchain L2ToL2CrossDomainMessenger ERC-7786 gateway adapter. sendMessage wraps the ERC-7930 envelope as the calldata the messenger will execute on the sibling adapter and dispatches via messenger.sendMessage (no fee — the relayer pays gas at relayMessage); receiveCrossChainMessage is the messenger-invoked delivery callback that authenticates the source out-of-band via crossDomainMessageContext, de-duplicates, and delivers to the ERC-7930 recipient. EVM (Superchain) chains only. Routes by BARE EVM chainId — no eid/selector translation.

INVERTED INBOUND AUTH: the adapter's inbound function is the _target the messenger CALLs during relayMessage, so msg.sender is the messenger predeploy (NOT the remote gateway). Trust is therefore established by reading the authenticated (sender, source) back from messenger.crossDomainMessageContext() and matching sender to the registered remote adapter for source. The messenger self-dedups on the message hash (relayMessage reverts on replay via successfulMessages), so the per-envelope guard here is cheap defense-in-depth rather than the primary replay defense. Wire message = abi.encodeCall(receiveCrossChainMessage, (senderInterop, recipient, payload)).

Functions

l2ToL2CrossDomainMessengerGatewayAdapterStorage

function l2ToL2CrossDomainMessengerGatewayAdapterStorage()
        internal
        pure
        returns (L2ToL2CrossDomainMessengerGatewayAdapterStorage storage $);

Returns

NameTypeDescription
$L2ToL2CrossDomainMessengerGatewayAdapterStorage

__L2ToL2CrossDomainMessengerGatewayAdapter_init

Registers the gateway-source ERC-165 id. The messenger is the fixed predeploy constant, so there is no endpoint/router to persist at init.

function __L2ToL2CrossDomainMessengerGatewayAdapter_init() internal;

registerInterface

Writes true to the SHARED IERC7786GatewaySource ERC-165 map slot (0x11967553 → ...). Same slot the CCIP/LayerZero/Wormhole/Axelar adapters register; a Diamond mounts at most one gateway.

function registerInterface() internal;

messenger

function messenger() internal pure returns (address);

Returns

NameTypeDescription
<none>address

getRemoteAdapter

function getRemoteAdapter(uint256 chainId) internal view returns (address);

Parameters

NameTypeDescription
chainIduint256

Returns

NameTypeDescription
<none>address

supportsAttribute

No sendMessage attributes are supported by this adapter: gas is supplied by the relayer at relayMessage, so there is no per-destination gas config to attach.

function supportsAttribute(bytes4) internal pure returns (bool);

Parameters

NameTypeDescription
_bytes4

Returns

NameTypeDescription
<none>bool

registerRemoteAdapter

function registerRemoteAdapter(uint256 chainId, address remoteAdapter) internal;

Parameters

NameTypeDescription
chainIduint256
remoteAdapteraddress

sendMessage

ERC-7786 source. Wraps the ERC-7930 envelope as the calldata the messenger will execute on the destination sibling adapter and dispatches it via messenger.sendMessage. Charges NO fee: gas is supplied by the relayer at relayMessage and the messenger takes no native value, so a non-empty msg.value is rejected. Returns the messenger's message hash as the ERC-7786 sendId.

No attributes are supported — any attribute reverts UnsupportedAttribute.

function sendMessage(bytes calldata recipient, bytes calldata payload, bytes[] calldata attributes)
        internal
        returns (bytes32);

Parameters

NameTypeDescription
recipientbytes
payloadbytes
attributesbytes[]

Returns

NameTypeDescription
<none>bytes32

receiveCrossChainMessage

Messenger-invoked delivery callback (INVERTED AUTH). Authenticates: (1) msg.sender is the messenger predeploy; (2) the authenticated cross-domain (sender, source) read from crossDomainMessageContext() matches the registered (non-zero) remote adapter for source. De-dups per (source, envelope id) marking BEFORE delivery (strict CEI), then delivers to the ERC-7930 recipient after asserting it targets THIS chain.

The per-envelope guard is defense-in-depth: the messenger already self-dedups on the message hash, reverting relayMessage on replay via successfulMessages.

function receiveCrossChainMessage(
        bytes calldata sender,
        bytes calldata recipient,
        bytes calldata payload,
        uint256 nonce
    ) internal;

Parameters

NameTypeDescription
senderbytes
recipientbytes
payloadbytes
nonceuint256