Skip to content
Lattice

AcrossBridgeAdapter

Git Source

Inherits: IAcrossBridgeAdapter, AcrossMessageHandler

Title: AcrossBridgeAdapter

Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from Across (https://github.com/across-protocol/contracts)

Across v3 intent/optimistic token-bridge facet: deposit escrows the input token on this chain toward an ERC-7930 recipient (a relayer fronts the output token on the destination and is later reimbursed via UMA optimistic settlement); handleV3AcrossMessage is the SpokePool-authenticated fill-time delivery hook. Across is an INTENT bridge with NO guaranteed fill — an unfilled deposit past fillDeadline is refunded ON THIS CHAIN to the depositor (always the calling user). It is NOT an ERC-7786 message gateway (no receiveId, no source attribution) and NOT burn/mint — this facet is deliberately not an IERC7786GatewaySource and never routes through OpenBridge.

Stateless delegator — logic/storage live in AcrossBridgeAdapterLib. The outbound deposit is nonReentrant with strict CEI and exact-amount approval hygiene and is NOT payable (ERC-20 inputs only in v1; native ETH users wrap first). Inbound fills are relayer-pushed and optimistic — NOT yet UMA-finalized when the hook runs (treat received funds/messages as reversible-until-finalized).

Notes:

  • lattice-version: 0.1.0
  • lattice-source: Across

Functions

deposit

Escrows params.inputAmount of params.inputToken (pulled from msg.sender) as an Across v3 deposit intent toward the ERC-7930 params.recipient on params.destinationChainId.

REFUND SAFETY: the deposit's depositor is always msg.sender (the calling user) — NEVER the diamond — because Across refunds an expired unfilled deposit ON THIS CHAIN to depositor, and depositor alone may speed up the deposit. NOT payable: ERC-20 inputs only in v1 (the SpokePool requires msg.value == 0 for non-wrapped-native inputs; native ETH users wrap first). Approves the SpokePool for EXACTLY inputAmount, then resets the allowance to 0.

function deposit(DepositParams calldata params) external virtual;

Parameters

NameTypeDescription
paramsDepositParams

handleV3AcrossMessage

SpokePool-invoked fill-time delivery hook (see the vendored AcrossMessageHandler): reverts AcrossNotSpokePool unless called by the configured SpokePool, then emits AcrossMessageReceived. NOTHING else in v1 — no handler registry; the diamond itself is the recipient and other facets manage the received funds.

OPTIMISTIC: fills are relayer-pushed and NOT yet UMA-finalized when this runs — treat received funds / message content as reversible-until-finalized. Never routed into OpenBridge (no M-of-N confirmation, no receiveId).

function handleV3AcrossMessage(address tokenSent, uint256 amount, address relayer, bytes calldata message)
        external
        virtual
        override(IAcrossBridgeAdapter, AcrossMessageHandler);

Parameters

NameTypeDescription
tokenSentaddress
amountuint256
relayeraddress
messagebytes

spokePool

The LOCAL chain's canonical Across v3 SpokePool (set once at init, no admin surface).

function spokePool() external view virtual returns (address);

Returns

NameTypeDescription
<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 AcrossBridgeAdapter methodIdentifiers (alphabetical by signature); kept in exact parity by ExportSelectorsParityTest. Chunks: deposit((bytes,bytes32,address,uint256,uint256,uint256,bytes32,uint32,uint32,uint32,bytes)) 0xd3948fec handleV3AcrossMessage(address,uint256,address,bytes) 0x3a5be8cb spokePool() 0xafdac3d6

function exportSelectors() external pure virtual returns (bytes memory selectors);

Returns

NameTypeDescription
selectorsbytes