Skip to content

Stuck-funds rescue mechanism for stealth-sender #22

@truthixify

Description

@truthixify

Labels: Stellar Wave, stellar, feature, security, drips, help-wanted
Tier: L (1–2 weeks)
Type: feature

Context

stealth-sender::send is supposed to be atomic: either the transfer + announcement both succeed, or both fail. But Soroban's auth/CPI model is rich enough that we can construct edge cases where funds might be transferred but the announcement panics — leaving funds at a stealth address with no on-chain announcement, making them effectively unrecoverable.

The audit (#03) will tell us if any such path exists. Regardless, we should have a rescue mechanism for the worst case.

Scope

This issue has two parts: a defensive contract change and a rescue tool.

Part 1: defensive contract change

Audit stealth-sender::send to confirm atomicity holds today. If it does — and we expect it does — keep this as a documented invariant via MAINNET_READINESS.md and skip Part 2 implementation.

If atomicity does NOT hold (the audit finds a gap), close it. Document the gap and the fix in contracts/stellar/POSTMORTEMS.md.

Part 2: rescue tool

For the hypothetical case where funds land at a stealth address without a matching announcement (operator error, partial chain reorg, future bug), build:

  1. A CLI tool scripts/rescue-stealth-funds.ts:
    • Input: sender's wallet, expected recipient meta-address, ephemeral pubkey, amount, asset.
    • Recomputes the stealth address using the SDK.
    • Queries the stealth address's balance.
    • If the balance matches, generates a post-hoc announcement signed by the sender and broadcasts it via the standard announcer contract.
    • The recipient can then scan normally and recover.
  2. Documentation explaining when to use this and the trust assumptions:
    • Sender must still have the ephemeral private key (or be able to regenerate it via deterministic derivation if available).
    • The "rescue" only restores findability, not the original tx hash.
  3. Make the tool refuse to operate if the stealth address has already moved funds (it would be a no-op anyway).

Constraints

  • The rescue tool must NEVER request the sender's spending key. It only needs the ephemeral key and the recipient meta-address.
  • The tool must clearly disclose: "This is a recovery mechanism. The original payment is final, but the recipient can now find it."

Acceptance criteria

  • Audit confirms or breaks the atomicity assumption.
  • If broken: fix landed and tested.
  • Rescue CLI built with tests against a fixture stealth address.
  • Documentation written.
  • Linked from the mainnet readiness doc (#20).

Why this matters

No one wants to be the team that says "your funds are lost, here's a sympathy email." Building the rescue path before we need it costs us a few days. Needing it without building it first costs us a user.

Metadata

Metadata

Assignees

Labels

Stellar WaveIssues in the Stellar wave programdripsFunded via Drips NetworkfeatureNew feature workhelp wantedExtra attention is neededsecuritySecurity-sensitive workstellarTouches Stellar / Soroban code

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions