Skip to content

Add USDT0 (LayerZero OFT) to the cross-chain and assets skills #115

Description

@kaankacar

Summary

USDT0 is live on Stellar mainnet. It is Tether's USDT delivered over LayerZero's OFT standard, and it is the first production OFT on Stellar's LayerZero endpoint. The skills do not mention USDT0, LayerZero, or OFT. An agent using cross-chain cannot route "bridge USDT to Stellar". An agent using assets has no example of a live asset whose admin is a contract and that ships without a stellar.toml.

LayerZero coverage was pulled from #67 on 2026-08-04 because Stellar testnet could not send (#1213 UnsupportedMessageLib). USDT0 now runs on the mainnet endpoint in production, so the follow-up promised there has a concrete anchor.

Docs side is covered by stellar/stellar-docs#2795 (short link-out page). This issue is the skill side, which should carry the verification detail the docs page leaves out.

Verified on mainnet (2026-08-25, read-only RPC and Horizon)

Surface Value
Classic asset USDT0:GATISXX6BZ6NC7IKQBY37CJD4SOZL3CYZJWXEDG6JVIY4WBS6KXJHN6Q
SAC CBSJZEIO5C7KC2SF3MKSNXXJSW5G3VTNBX4ATMKUI3B2MR4JKM4R26YF (derivation verified)
OFT contract CBOWOLFSDM5PZXNFIVDMP5NZ7U2GSIHED6H6R446QOHF266XINKUMMF6
Mint/burn adapter, also SAC admin CA3GUWLOS3QKN6WNRAELSUDSKLDTVTWEDJ3KLGAJG3SIWGA5L3KZYWGJ
LayerZero EndpointV2 (mainnet, EID 30600) CCQLLRE5JBAWYCW3KTWOIWLMFDUOKROQVZNSALQMGOSXNW3ERUOWTZGK
LayerZero testnet endpoint (EID 40600) CALTBA5S6GRJEHAXFP45LGGLKWWAF7HTZCPNUBUJF2HWWRRLQNV35AIV

Facts an agent needs:

  • Issuer flags: auth_revocable and auth_clawback_enabled set. auth_required and auth_immutable not set. USDC on Stellar sets auth_revocable only.
  • Issuer account is locked: master key weight 0, no other signers. Flags cannot change through SetOptions.
  • No home_domain, so no SEP-1 stellar.toml. Any check keyed on home_domain or [[CURRENCIES]] fails. SAC name() returns USDT0:G..., symbol() returns USDT0.
  • SAC admin() is the adapter contract above. Its interface exposes mint, set_authorized, clawback, set_admin, upgrade, role gated. Its owner() is another contract, CBCZ5CETG3XR5MZVDC7QBDOTIH6P7MOLUH2SSC52J3NVBYIV45D4QKR6.
  • Decimals: SAC decimals() is 7. OFT shared_decimals() is 6, decimal_conversion_rate() is 10. quote_oft with amount_ld 10000001 returns amount_sent_ld 10000000. Dust below 6 decimals is dropped on send.
  • OFT: oft_type() is MintBurn(adapter). token() equals the SAC. is_paused() false. default_fee_bps() null. Rate limits exist per pathway (rate_limit_config).
  • Peers set for EIDs 30101 (Ethereum), 30110 (Arbitrum), 30111 (Optimism). None for 30184 (Base) or 30102 (BSC). Peers are live data. Query peer(eid), do not hardcode.
  • Fees for outbound sends are paid in XLM. quote_send returns MessagingFee. quote_oft returns OFTLimit, fee details, and OFTReceipt.
  • USDT0 publishes no testnet deployment. Everdawn Labs builds and operates USDT0 (usdt0.to footer).

Proposed changes

skills/cross-chain

  1. Add a companion file layerzero.md. Mirror the cctp.md structure:
    • Contracts and addresses (endpoint, ULN, executor, DVNs from the LayerZero metadata API; USDT0 addresses above).
    • The rule that saves funds: recipient trustline before inbound; pin code and issuer; 7 vs 6 decimals with a worked dust example.
    • OFT concept in one screen: peers, DVNs, executor, lz_receive, mint/burn vs lock/unlock.
    • Inbound flow (EVM to Stellar) and outbound flow (Stellar to EVM) with the exact SendParam struct, quote_oft, quote_send, send, and CLI arg shapes. Read-only simulation examples first.
    • Tracking on LayerZero Scan. Timing stays qualitative: minutes, driven by source-chain finality.
    • Limitations and status notes: pause flag, rate limits, fee bps, no USDT0 testnet, testnet send status.
  2. Update SKILL.md:
    • Router row: move native USDT between Stellar and an EVM chain, use USDT0 over LayerZero OFT, see layerzero.md.
    • Frontmatter description and "Rules of thumb" mention the new rail.
    • Shared pitfall 2 (decimals): add OFT shared decimals and dust removal.
    • Shared pitfall 5 (testnet first): state that USDT0 has no testnet deployment and give the rehearsal path.
  3. Restore the compile-verified OApp skeleton from Add official cross-chain skill: CCTP V2, Axelar GMP/ITS, NEAR Intents #67 branch history (631db31 removed it, the custom = [receiver] footgun fix is in a79b4df). Re-verify against current crates before it ships.

skills/assets

  1. In the "SAC admin contract" note under "Use Custom Contract Tokens When", cite USDT0 as the live example: locked issuer, contract admin with mint, set_authorized, clawback.
  2. In "Security" best practices, add two lines. Some live assets have no stellar.toml; validate by issuer plus SAC derivation, not by home_domain. When auth_revocable and auth_clawback_enabled are set, identify who holds the admin role before listing.
  3. Add a short read-only "pre-listing check" recipe with USDT0 as the example: stellar ledger entry fetch account, stellar contract id asset, stellar contract invoke ... -- decimals|name|symbol|admin, and the OFT reads token, shared_decimals, oft_type, endpoint, is_paused. No keys, no signing. The docs page dropped this on purpose; the skill is the right home for it.

Site

  • site/src/data/skills.ts: the cross-chain card reads "Cross-Chain (CCTP, Axelar)". Add LayerZero.

Verification plan for the PR

  • Re-run every read-only check above against mainnet and record the date. Fail the PR if any value moved without an explanation.
  • Compile the OApp skeleton to wasm32v1-none against current LayerZero crates.
  • Re-test Stellar testnet send. If #1213 UnsupportedMessageLib still reproduces, document it as a status note instead of blocking the file.
  • Mainnet: simulation only (quote_oft, quote_send). No funds moved by the PR.
  • Stress test with fresh agents, as done for Add wallet skill: use the Stellar CLI as a wallet #49 and Add DeFi skill index and Blend v2 lending/backstop playbook #55. Prompts: "bridge USDT from Arbitrum to Stellar", "send USDT0 from Stellar to Ethereum", "is USDT0 safe collateral for my lending protocol", "why does my USDT0 send lose the last digit".

Out of scope

  • No fee, cap, or per-route timing numbers. Point agents at quote_send, quote_oft, and rate_limit_config.
  • No changes to stellar-docs. #2795 covers the docs page.
  • No partner or exchange lists.

References

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentationenhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions