Skip to content
$1,000,000 in security audit grants are live now, Apply here →

Security review · August 2026

Stellar Contracts

for USDT0

Guardian's review of Stellar Contracts for USDT0, published August 2026. The report records 4 findings, including 4 informational.

Published
Review window
August 7 to 11, 2026
Language
Rust, Soroban
Chains
Stellar
Sector
Stablecoins
  • 0 Critical
  • 0 High
  • 0 Medium
  • 0 Low
  • 4 Informational

4 acknowledged

Scope

Findings 4

  1. I-01 Informational Stellar Trustline Gaps Block OFT Delivery Documentation Acknowledged

    Description

    The EVM OFT accepts a 32-byte destination but cannot determine whether the corresponding Stellar recipient can hold the Stellar asset. After tokens are burned on EVM, the Stellar OFT resolves the payload as a deployed C-address or, if no corresponding contract exists, as a G-address and attempts to mint through the Stellar Asset Contract. A classic Stellar account identified by a G-address can receive and hold an issued asset only through a trustline for that asset. Therefore, the recipient must have an authorized trustline whose remaining limit can accommodate the transferred amount. The Stellar OFT only invokes the mint operation and does not create a missing trustline, as trustline creation requires authorization from the recipient and sufficient XLM reserve. If these requirements are not satisfied, destination execution reverts after the source tokens have already been burned. The message remains retryable, but the tokens remain unavailable until the trustline is established or the intended contract is deployed and the message is retried.

    Recommendation

    Document that G-address recipients must exist and establish an authorized trustline for the Stellar asset before receiving an inbound transfer.

  2. I-02 Informational Stellar Pause Leaves Inbound Transfers Pending Documentation Acknowledged
    Location
    https://github.com/GuardianOrg/usdt0-oft-contracts-team1-1785973686068/blob/ef3db2a637a43f33dc17950afe4873d7c830c793/stellar-contracts/oft/src/oft.rs#L93-L140

    Description

    The Stellar pause mechanism blocks both outgoing debits and incoming credits. Outgoing transfers are pause protected indirectly, as both debit implementations invoke __debit_view before locking or burning tokens, and that function checks the pause state. Incoming transfers are rejected directly by __credit. This creates a cross-chain asymmetry because the EVM OFT has no corresponding pause mechanism and cannot prevent transfers targeting a paused Stellar deployment. An EVM-to-Stellar transfer can burn tokens successfully on EVM, after which destination execution reverts when Stellar attempts to credit the recipient. Conversely, a Stellar-to-EVM transfer is rejected before any Stellar tokens are locked or burned. The failed inbound message remains retryable, so the tokens are not lost. However, they remain unavailable until Stellar is unpaused and the message is retried.

    Recommendation

    Document that pausing Stellar also suspends settlement of transfers already initiated from other EVM chains. Monitor failed inbound deliveries and establish a process to retry them after unpausing.

  3. I-03 Informational Quoted Maximum Ignores Dust Rounding Rounding Acknowledged

    Description

    The quote_oft function derives the maximum input from the available outbound rate limit capacity. When a fee is configured, the contract converts the available post-fee capacity into an estimated maximum pre-fee input, intending the result to represent the largest input accepted by send.

            let mut max_amount_ld = Self::rate_limit_capacity(env, &Direction::Outbound, send_param.dst_eid);
            if max_amount_ld != i128::MAX {
                // Back-calculate pre-fee amount so max_amount_ld represents the largest input to send()
                max_amount_ld = Self::__amount_before_fee(env, send_param.dst_eid, max_amount_ld);
            } else {
                // No rate limit configured — use the bounded default
                max_amount_ld = u64::MAX as i128;
            }
            limit.max_amount_ld = max_amount_ld;
    

    However, during execution, the contract rounds the amount down according to the decimal conversion rate before applying the rate limit.

            let (amount_sent_ld, amount_received_ld) = if !has_fee {
                // No fee: dust stays with sender (default OFT behavior)
                let amount_sent_ld = oft_utils::remove_dust(amount_ld, conversion_rate);
                (amount_sent_ld, amount_sent_ld)
            } else {
                // With fee: match EVM OFTFee behavior
                // - sender pays full amount_ld (no dust removed), dust is absorbed into the charged fee
                let fee = Self::__fee_view(env, dst_eid, amount_ld);
                let amount_received_ld = oft_utils::remove_dust(amount_ld - fee, conversion_rate);
                (amount_ld, amount_received_ld)
    

    The rate limiter consequently checks the normalized amount_received_ld, rather than the original input. As a result, inputs above the reported maximum can still be accepted when fee calculation and dust removal round them down to an amount within the available capacity. Consequently, integrations relying on the quoted maximum may unnecessarily reject valid transfers.

    Recommendation

    Calculate max_amount_ld using the same fee and dust rounding as send, so it reflects the largest accepted input.

  4. I-04 Informational Unsafe Single-Step SAC Admin Transfer Best Practices Acknowledged

    Description

    The SAC Manager allows an account holding ADMIN_MANAGER_ROLE to transfer SAC administration immediately to any supplied address. The new administrator is not validated and is not required to accept the transfer. After execution, the Manager loses SAC authority and cannot restore itself because any subsequent administrative transfer must be authorized by the new administrator. Consequently, transferring administration to an incorrect or nonfunctional address can permanently disable minting and other SAC administrative operations.

    Recommendation

    Implement a two-step transfer in which the current administrator proposes a new administrator and the proposed administrator authenticates an acceptance before the Manager calls the SAC’s set_admin.

More from USDT0

All 35 reports
  1. USAT Reconfiguration

    1 finding 1 finding: 1 low
  2. Stellar Deployment

    2 findings 2 findings: 2 informational
  3. Corn Network Delisting

    1 finding 1 finding: 1 low
  4. Canary Chain Configuration Verification

    4 findings 4 findings: 4 informational

Put your code through the same review.

This review started with a conversation about scope. Tell us what you are building and we will plan yours with you.

Get a quote