Skip to content
Lattice

IStargateBridgeAdapter

Git Source

Title: IStargateBridgeAdapter

Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from Stargate (https://github.com/stargate-protocol/stargate-v2)

Read / admin / action surface of the Stargate v2 POOLED-LIQUIDITY token-bridge adapter — the third token rail beside CCTP (burn/mint) and Across (intent): sendToken pulls the token from the caller and deposits it into the LOCAL Stargate pool, which debits shared unified liquidity so the DESTINATION pool releases the token to the recipient. OUTBOUND-ONLY for plain transfers: the destination-side receiver is Stargate's own pool (the LayerZero OApp), NOT a Lattice facet — there is no Lattice inbound surface, no receiveId, no source attribution, and this is never routed through OpenBridge. composeMsg/lzCompose hooks and bus mode are DEFERRED (see sendToken).

Stargate rides LayerZero: destinations are keyed by the LayerZero uint32 eid (admin-registered bidirectional chainId ⇄ eid map, never inferred), and msg.value is the LayerZero messaging fee EXCLUSIVELY — ERC-20 pools only in v1. Native-ETH pools (StargatePoolNative, where msg.value mixes fee + send amount) are DEFERRED and MUST NOT be registered. Per-token pools are admin-registered identities (register once, no re-pointing in v1) with a fail-closed pool.token() cross-check.

Functions

stargateEidOf

The LayerZero eid registered for chainId (0 = unset).

function stargateEidOf(uint256 chainId) external view returns (uint32);

Parameters

NameTypeDescription
chainIduint256

Returns

NameTypeDescription
<none>uint32

stargateChainIdOf

The EVM chainId registered for eid (0 = unset).

function stargateChainIdOf(uint32 eid) external view returns (uint256);

Parameters

NameTypeDescription
eiduint32

Returns

NameTypeDescription
<none>uint256

poolOf

The Stargate pool registered for token (0 = unset).

function poolOf(address token) external view returns (address);

Parameters

NameTypeDescription
tokenaddress

Returns

NameTypeDescription
<none>address

quoteSendFee

Quotes the LayerZero native fee of a send, building the IDENTICAL SendParam the send path dispatches (same internal builder — quote/send can never drift).

function quoteSendFee(SendTokenParams calldata p) external view returns (uint256 nativeFee);

Parameters

NameTypeDescription
pSendTokenParams

Returns

NameTypeDescription
nativeFeeuint256

registerStargateEid

Registers an EVM chainId ↔ LayerZero eid equivalence (both directions, fail-loud — identities are never remapped; zero chainId/eid rejected). Admin only.

Stargate rides LayerZero, so the eid here equals the LayerZero adapter's eid for the same chain — recorded in this adapter's OWN map (adapters never share hot-path storage).

function registerStargateEid(uint256 chainId, uint32 eid) external;

Parameters

NameTypeDescription
chainIduint256
eiduint32

registerPool

Registers token's Stargate pool (identity — register once; StargateTokenAlreadyRegistered on a duplicate). FAIL-CLOSED: reverts StargatePoolTokenMismatch unless pool.token() == token. Admin only.

ERC-20 pools only in v1 — never register a StargatePoolNative (its token() is address(0), so the zero-token guard rejects it structurally). A pool upgrade cannot re-point an existing token entry in v1 (deliberate YAGNI): ship a new adapter config instead.

function registerPool(address token, address pool) external;

Parameters

NameTypeDescription
tokenaddress
pooladdress

sendToken

Sends p.amountLD of p.token (pulled from msg.sender) through its registered Stargate pool toward the ERC-7930 p.recipient on p.destinationChainId. msg.value is the LayerZero fee EXCLUSIVELY (quoted precheck; excess refunds to msg.sender, never the diamond).

TAXI ONLY (issue #77 Q11): the send is dispatched with EMPTY oftCmd (immediate/taxi mode) and EMPTY composeMsg/extraOptions — bus mode (deferred batched sends) and lzCompose destination hooks are DEFERRED to a future revision. DUST SWEEP: pools truncate amountLD to shared decimals, so the pool may debit less than was pulled; the exact un-debited remainder is returned to msg.sender in the same call and the diamond nets zero.

function sendToken(SendTokenParams calldata p)
        external
        payable
        returns (bytes32 guid, uint256 amountSentLD, uint256 amountReceivedLD);

Parameters

NameTypeDescription
pSendTokenParams

Returns

NameTypeDescription
guidbytes32The LayerZero message guid.
amountSentLDuint256The amount the pool ACTUALLY debited (post dust truncation).
amountReceivedLDuint256The amount credited on the destination (post pool fees).

Events

RegisteredEid

Emitted when an EVM chainId ↔ LayerZero eid equivalence is registered (identity; fail-loud).

event RegisteredEid(uint256 indexed chainId, uint32 eid);

Parameters

NameTypeDescription
chainIduint256
eiduint32

RegisteredPool

Emitted when a token's Stargate pool is registered (identity; register once).

event RegisteredPool(address indexed token, address indexed pool);

Parameters

NameTypeDescription
tokenaddress
pooladdress

StargateTokenSent

Emitted when a Stargate send is dispatched. amountSentLD is what the pool ACTUALLY debited (may be less than the requested amount — dust already swept back to the sender); amountReceivedLD what the destination credits after pool fees.

event StargateTokenSent(
        address indexed sender,
        address indexed token,
        uint256 indexed destinationChainId,
        bytes32 guid,
        uint256 amountSentLD,
        uint256 amountReceivedLD,
        bytes32 recipient
    );

Parameters

NameTypeDescription
senderaddress
tokenaddress
destinationChainIduint256
guidbytes32
amountSentLDuint256
amountReceivedLDuint256
recipientbytes32

Errors

StargateZeroAddress

A required address argument (token or pool in registerPool) was the zero address.

error StargateZeroAddress();

StargateZeroChainId

The chainId being registered was 0 (0 is the unset sentinel of the eid ⇒ chainId map).

error StargateZeroChainId();

StargateZeroEid

The eid being registered was 0 (0 is the unset sentinel of the chainId ⇒ eid map).

error StargateZeroEid();

StargateEidAlreadyRegistered

An eid equivalence is already registered for this chainId or eid (fail-loud, both maps — identities are never remapped).

error StargateEidAlreadyRegistered(uint256 chainId, uint32 eid);

Parameters

NameTypeDescription
chainIduint256
eiduint32

StargateTokenAlreadyRegistered

The token already has a registered pool (identity — a pool upgrade cannot re-point a token entry in v1; deliberate YAGNI).

error StargateTokenAlreadyRegistered(address token);

Parameters

NameTypeDescription
tokenaddress

StargatePoolTokenMismatch

FAIL-CLOSED registration cross-check: pool.token() does not match the token being registered — a mis-registered pool would burn user approvals against the wrong asset.

error StargatePoolTokenMismatch(address expected, address actual);

Parameters

NameTypeDescription
expectedaddress
actualaddress

StargateTokenNotRegistered

The token has no registered Stargate pool.

error StargateTokenNotRegistered(address token);

Parameters

NameTypeDescription
tokenaddress

StargateUnknownDestinationChain

The destination chain has no registered LayerZero eid.

error StargateUnknownDestinationChain(uint256 chainId);

Parameters

NameTypeDescription
chainIduint256

StargateSameChain

The send targeted this chain (destinationChainId == block.chainid).

error StargateSameChain(uint256 chainId);

Parameters

NameTypeDescription
chainIduint256

StargateZeroAmount

The send amountLD was zero.

error StargateZeroAmount();

StargateZeroMinAmount

The send minAmountLD was zero (the mandatory slippage floor — pools charge fees, so 0 would mean unlimited slippage).

error StargateZeroMinAmount();

StargateDestinationMismatch

The ERC-7930 recipient declares an eip-155 chain that differs from destinationChainId.

error StargateDestinationMismatch(uint256 declaredChainId, uint256 givenChainId);

Parameters

NameTypeDescription
declaredChainIduint256
givenChainIduint256

StargateChainReferenceTooLong

The chain reference decoded from the ERC-7930 recipient does not fit in a uint256.

error StargateChainReferenceTooLong(uint256 length);

Parameters

NameTypeDescription
lengthuint256

StargateInsufficientFee

msg.value was below the quoted LayerZero native fee (precheck, before any funds move).

error StargateInsufficientFee(uint256 required, uint256 provided);

Parameters

NameTypeDescription
requireduint256
provideduint256

Structs

SendTokenParams

Caller-supplied parameters of a Stargate sendToken (struct avoids stack-too-deep).

struct SendTokenParams {
        /// @notice ERC-7930 interoperable address of the destination recipient (20-byte EVM or up-to-32-byte
        ///         non-EVM address field; down-converted to a right-aligned `bytes32`).
        bytes recipient;
        /// @notice The LOCAL ERC-20 sent through its registered Stargate pool.
        address token;
        /// @notice Amount of `token` (local decimals) pulled from the caller. The pool may debit LESS
        ///         (shared-decimal dust truncation) — the un-debited remainder is swept back to the caller.
        uint256 amountLD;
        /// @notice MANDATORY slippage floor (local decimals) on the destination-credited amount. Stargate
        ///         pools charge fees, so output < input; 0 would mean unlimited slippage and is rejected.
        uint256 minAmountLD;
        /// @notice EVM chainId of the destination chain (resolved to the registered LayerZero eid and
        ///         cross-checked against the ERC-7930 recipient's chain reference for eip-155 recipients).
        uint256 destinationChainId;
    }

Properties

NameTypeDescription
recipientbytes
tokenaddress
amountLDuint256
minAmountLDuint256
destinationChainIduint256