Stargate lets apps attach destination contract calls to V2 taxi transfers
Stargate lets apps move tokens across supported chains and request additional execution in a destination contract. A direct V2 integration on EVM chains specifies transfer parameters, quotes token output and messaging fees, then calls send() or sendToken(). Destination automation requires a compatible receiver, a compose payload and sufficient execution gas. Taxi mode supports that callback, and the app tracks token delivery separately from execution of its requested action. Those states determine when it can credit a transfer or continue another operation.
V2 contract entry points and route availability
V2’s send() and sendToken() entry points accept structured instructions for a supported asset and destination. Their SendParam structure carries the destination endpoint identifier, recipient, amount and minimum output. Additional fields specify execution options, compose instructions and delivery mode; an empty oftCmd selects taxi. Liquidity pools and Hydra omnichain fungible token (OFT) deployments share the transfer interface. Pools hold and pay out underlying assets; Hydra OFTs burn backed tokens on send and mint them on receipt. Route compatibility remains specific to the selected token and connected destinations; a token ticker alone cannot identify the appropriate deployment.
Stargate’s delivery policy specifies taxi for all its transactions from October 1, 2026. Older V2 bus interfaces do not establish batching availability for a new integration.
Token output, messaging fees and spending authority
quoteOFT() estimates token output and transfer limits, while quoteSend() estimates the cross-chain messaging charge. Source transaction gas adds a cost outside either quote.
Limits and minimum output
Local decimals express an amount in the reporting contract’s token precision. The sending contract uses these units for amountLD and minAmountLD. quoteOFT() returns a projected receipt and pathway limits. Its calculation can cap the requested input at available credits, which represent transfer capacity. A capped quote does not promise a partial send; post-fee output above available credits makes the transaction revert. The app should check both returned limits; input below the minimum rounds to zero and quoteSend() rejects it. minAmountLD protects bridge output; a destination swap needs its own minimum-output condition.
Messaging and execution budgets
quoteSend() prices the prepared transfer parameters and execution options, so changes to compose instructions or gas budgets can change its quote. The app should quote the parameters that it will actually submit. The lzCompose execution option allocates gas for the destination callback. The callback’s code and destination chain determine its required budget. A native-token V2 transfer also supplies the transferred principal through msg.value alongside the messaging fee.
The balance that the bridge debits
ERC-20 allowances authorize a spender to use a particular owner’s tokens. When an app contract calls a direct V2 token transfer, the bridge debits that contract’s balance. The contract must therefore hold the input tokens and supply the required bridge allowance. A user’s allowance to the app concerns a different owner-spender relationship. Native-asset transfers supply value directly, so this ERC-20 allowance explanation applies to token transfers that require approval.
Compose payloads and receiver authentication
A nonempty composeMsg attaches instructions to a taxi transfer for execution at its receiving contract. The receiver must implement ILayerZeroComposer and lzCompose().
Payload encoding and token amounts
The sender encodes application arguments into composeMsg; the receiving contract decodes them using the same agreed structure. Stargate delivers a surrounding message that includes transfer information. OFTComposeMsgCodec separates the application payload from that envelope and exposes the received amount. The receiver should use the delivered amount for its token operation. A destination swap can carry an output token, beneficiary, minimum output and deadline, provided the app supports and validates those arguments.
Endpoint and sender checks
The receiver authenticates both the local LayerZero Endpoint and the Stargate contract that submitted its compose message. Checking msg.sender alone establishes only the Endpoint’s involvement. The callback’s _from argument identifies the originating contract on the destination chain. The receiver also needs application-level controls over permitted operations and beneficiaries. Forwarding payload instructions into unrestricted external calls would let the payload choose how the contract uses its tokens.
Delivery records and callback outcomes
A successful source send records dispatch, while destination token receipt establishes a different state. The message GUID links the corresponding records across chains.
Stargate emits OFTReceived after delivering tokens to the designated recipient. A reverted LayerZero receive transaction needs a receive retry after resolving its cause. V2 caches receive data when the recipient transfer or mint returns a failure. retryReceiveToken() addresses that cached failure using matching transfer details. A failure inside a queued compose call needs the compose mechanism’s recovery path instead.
LayerZero executes queued compose calls separately from token receipt. A callback revert leaves its queued message retryable. Another attempt still needs matching message data and adequate gas. Additional gas cannot repair an expired swap deadline or invalid application arguments.
ComposeDelivered confirms that the callback returned successfully. A receiver that catches an unsuccessful external swap can still return successfully. The app needs the actual output asset and amount credited to the beneficiary to distinguish a swap from its fallback.
Should an app attach a swap or leave it for a later transaction?
A composed swap suits a predefined destination action; a later transaction allows the app to confirm swap terms after arrival. Consider an app that needs the transferred token exchanged for another supported destination token. Both designs require a valid swap route and acceptable output. Both also need confirmation that the intended output token reaches the selected beneficiary.
- Attach the swap when a compatible receiver can execute the agreed instructions with the allocated compose gas.
- Leave the swap for a later destination transaction when its terms need fresh confirmation after token delivery.
- For either design, enforce the swap’s minimum output and deadline; cross-chain transit can invalidate precommitted terms.
- If execution stalls, distinguish failed token receipt from a callback revert before choosing the applicable retry mechanism.
- Continue after the intended output reaches the beneficiary; receipt of the incoming bridge token alone does not complete the swap.
A retry can address insufficient execution gas while the queued instructions remain valid. It cannot bypass the destination contract’s deadline. A receiver’s fallback policy determines what happens to delivered tokens when the requested swap cannot execute.
API migration and integration testing
The older Stargate API carries a deprecation notice directing integrations to the LayerZero Value Transfer API. Direct V2 contract calls remain a separate integration approach. The replacement API supplies discovery information, transfer quotes and execution steps. In its ERC-20 flow, TransferDelegate is the approval spender and LZMulticall executes the bridge transaction. The approval transaction’s target is the token contract. Approving LZMulticall as a token spender can let anyone drain the approved tokens.
Integration tests should exercise the selected deployment’s successful transfer and the receiver’s failure behavior. Callback authentication, payload decoding and execution gas affect whether destination logic completes. Tests also need to distinguish a reverted callback from a callback that successfully chooses its fallback. API integrations should preserve the returned execution order and associate status tracking with the relevant transfer. An app can then report the delivered asset and completed action separately, giving its users a concrete account of their destination balance.
Questions people ask about Stargate
Is the destination endpoint identifier interchangeable with an EVM chain ID?
A destination endpoint identifier and an EVM chain ID belong to separate identifier systems. Direct V2 calls use the LayerZero endpoint identifier in dstEid. Wallet network selection uses the chain ID. Substituting one for the other can address an incorrect or unsupported destination.
Do app users need ZRO when messaging fees use the native token?
A direct V2 transfer quoted with quoteSend(sendParam, false) uses native-token payment for its messaging fee. This payment choice does not require ZRO for that charge. The sender still needs the transferred asset and source transaction gas. A native-asset transfer also includes its principal in the supplied value.
Why can a V2 token transfer leave a tiny remainder in the sending balance?
V2 converts token amounts into shared decimal precision and removes any unrepresentable remainder from the amount that it debits. For an ERC-20 pool transfer, that remainder stays in the sender’s balance. The conversion depends on the deployment’s local and shared decimals, so apps should reconcile actual debits using the transfer receipt.
Can a legacy V1 receiver handle V2 composed messages without changes?
A V1 sgReceive() implementation does not provide the V2 lzCompose() interface. V2 also uses a different message envelope and caller authentication model. A contract supporting both integrations must implement and secure their respective handlers; renaming the callback alone does not adapt the payload or its authorization checks.
Where should excess messaging fees go when an app initiates a direct transfer?
The refundAddress argument specifies the recipient of excess LayerZero messaging fees on the source chain. An app should set that address to the intended fee payer or refund recipient. This parameter does not designate the destination token beneficiary or create a refund policy for failed destination business logic.
How can a composer identify the account that initiated the source call?
OFTComposeMsgCodec.composeFrom() exposes the source caller that the taxi message encodes. If an app contract initiated the bridge call, this value identifies that contract. It does not automatically identify the wallet that called the app. The receiver must authenticate the message origin before using this field for application authorization.
When should an app replace a saved API quote?
Replace a saved API quote after its expiresAt timestamp passes or its transfer parameters change. Some quotes omit expiresAt. That omission does not establish permanent validity because fees, route availability and contract state can change. Any deadline inside the destination instructions remains a separate execution condition.
Why can the status API return UNKNOWN for a submitted transfer?
UNKNOWN means the service has not found the transfer or records it as not started. It does not confirm destination receipt or prove an on-chain reversal. Value Transfer API status requests for Stargate routes require the source transaction hash alongside the quote identifier. The app should reconcile those identifiers with the actual submitted transaction.