Skip to content

payment_escrow::emergency_drain can't recover XLM-denominated escrow funds #1020

Description

@martinzhames

Category: security, bug

Problem

payment_escrow supports two asset types, AssetType::Xlm and AssetType::Usdc (lines 12-15), and every normal transfer path (deposit, release, release_partial, expire, refund, resolve_dispute) is asset-type-aware via token_address()/transfer_from_contract(). However, emergency_drain (lines 503-553) hardcodes a single token: let usdc_token: Address = env.storage().instance().get(&DataKey::UsdcToken).unwrap(); and only ever transfers the contract's USDC balance to the emergency treasury. There is no equivalent path that reads DataKey::XlmToken and drains XLM-denominated escrow balances.

Impact

In a genuine emergency (e.g. a critical bug discovered in the escrow logic, or a compromised admin key actively draining funds through normal channels), the documented 3-of-3-signer emergency drain — the contract's designated last-resort fund-recovery mechanism per EMERGENCY_RUNBOOK.md — can rescue USDC but leaves any XLM held in escrow completely unprotected and unrecoverable through this path.

Suggested fix

Parameterize emergency_drain by AssetType (or add a second emergency_drain_xlm following the same 3-signer/cooldown logic) so both supported asset types can be swept to the treasury during an incident. Update EMERGENCY_RUNBOOK.md to document the XLM drain procedure once added.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Stellar WaveIssues in the Stellar wave programbugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions