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.
For the architecture, the OFT interface, supported chains, and the transfer UI:
Mainnet addresses
| Surface | Address |
|---|---|
| Classic asset | USDT0: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 mainnet | Value |
|---|---|
| Endpoint ID (EID) | 30600 |
| EndpointV2 contract | CCQLLRE5JBAWYCW3KTWOIWLMFDUOKROQVZNSALQMGOSXNW3ERUOWTZGK |
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:
- On the source chain, the OFT debits the sender and hands a message to the LayerZero endpoint.
- The decentralized verifier networks (DVNs) configured for that pathway wait for the source chain to reach the finality they require, then verify the message.
- An executor delivers the verified message to the destination endpoint, which calls
lz_receiveon the destination OFT. - 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:GATISXX6BZ6NC7IKQBY37CJD4SOZL3CYZJWXEDG6JVIY4WBS6KXJHN6Qonce. 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
CBSJZEIO5C7KC2SF3MKSNXXJSW5G3VTNBX4ATMKUI3B2MR4JKM4R26YFthrough 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_sendandsendfunctions, with fees paid in XLM. The USDT0 developer guide documents the OFT interface and the message flow. Queryquote_sendfor 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.