Skip to main content

Cross-Chain USDT0 Transfers with LayerZero

USDT0 brings Tether's USDT to other chains over LayerZero's Omnichain Fungible Token (OFT) standard. USDT is locked in an adapter contract on Ethereum, and the same amount of USDT0 is minted on the destination chain. Sending USDT0 out of a chain burns it there and unlocks or mints it on the destination, so total supply stays constant across chains.

On Stellar, USDT0 is a classic asset with a SAC. Classic flows use a trustline plus a payment. Soroban contracts call the SAC. See the tokenization model comparison for what that implies.

Full documentation

For the architecture, the OFT interface, supported chains, and the transfer UI:

Mainnet addresses

SurfaceAddress
Classic assetUSDT0:GATISXX6BZ6NC7IKQBY37CJD4SOZL3CYZJWXEDG6JVIY4WBS6KXJHN6Q
Stellar Asset Contract (SAC)CBSJZEIO5C7KC2SF3MKSNXXJSW5G3VTNBX4ATMKUI3B2MR4JKM4R26YF
OFT contract (LayerZero messaging)CBOWOLFSDM5PZXNFIVDMP5NZ7U2GSIHED6H6R446QOHF266XINKUMMF6

Many Stellar assets share the code USDT or USDT0. An asset's identity is its code and its issuer. Always pin the issuer above, and confirm that the SAC you derive from it matches the SAC address above.

How LayerZero fits

LayerZero V2 is a cross-chain messaging protocol. Every connected chain runs an endpoint contract, identified by an endpoint ID (EID). An OFT is an application built on that endpoint: one token contract per chain, each configured with the address of its peer on every other chain.

LayerZero on Stellar mainnetValue
Endpoint ID (EID)30600
EndpointV2 contractCCQLLRE5JBAWYCW3KTWOIWLMFDUOKROQVZNSALQMGOSXNW3ERUOWTZGK

Endpoint, message library, and executor addresses are published on LayerZero's Stellar deployment page and in the deployed contracts list.

A transfer works like this:

  1. On the source chain, the OFT debits the sender and hands a message to the LayerZero endpoint.
  2. The decentralized verifier networks (DVNs) configured for that pathway wait for the source chain to reach the finality they require, then verify the message.
  3. An executor delivers the verified message to the destination endpoint, which calls lz_receive on the destination OFT.
  4. The destination OFT credits the recipient. On Stellar, the OFT contract mints through a mint/burn adapter contract that holds the SAC admin role, and the USDT0 lands in the recipient's trustline or contract balance.

Transfer time depends on the source chain's finality and on DVN verification, not on Stellar's ledger close. A transfer out of Stellar is a single Stellar transaction on the sending side, and arrival depends on the destination chain. Track a transfer by its transaction hash on LayerZero Scan.

Integrate USDT0

USDT0 needs no special integration code on Stellar. Use the same paths as for any other Stellar asset with a SAC:

  • Classic accounts and wallets. The recipient opens a trustline to USDT0:GATISXX6BZ6NC7IKQBY37CJD4SOZL3CYZJWXEDG6JVIY4WBS6KXJHN6Q once. After that, any account holding USDT0 can send it with a payment operation. See Send and Receive Payments and Verify Trustlines.
  • Smart contracts. Call the SAC at CBSJZEIO5C7KC2SF3MKSNXXJSW5G3VTNBX4ATMKUI3B2MR4JKM4R26YF through the token interface, the same way as any other token. See Use Issued Assets in Smart Contracts with the SAC. A contract balance in USDT0 lives in the SAC, separate from account trustlines.
  • Bridging in or out. End users move USDT0 with the transfer UI. Programmatic sends from Stellar go through the OFT contract's quote_send and send functions, with fees paid in XLM. The USDT0 developer guide documents the OFT interface and the message flow. Query quote_send for the current fee rather than relying on a documented number.

Amount precision

Stellar assets have 7 decimal places, so the SAC's decimals() returns 7. The USDT0 OFT uses 6 shared decimals across all chains: the OFT contract's shared_decimals() returns 6 and its decimal_conversion_rate() returns 10. A cross-chain send drops anything below 6 decimals before the amount leaves Stellar. Quoting a send of 1.0000001 USDT0 returns an amount_sent_ld of 1.0000000.

Inside Stellar, payments and SAC transfers use all 7 decimals. If your protocol holds balances that users will later bridge out, round to 6 decimals so no dust gets stranded.