Skip to content

Build configurable contract-wide emergency withdrawal #233

Description

@Kingsman-99

Label: complexity: high
Points: 200

Description

If a critical, unpatchable bug is discovered, there's currently no way for admin to recover all custodied funds to a safe address in an emergency — pause() only stops new activity, it doesn't move existing custody. This issue adds a last-resort emergency withdrawal, intentionally heavily gated.

Technical Context

Involves lib.rsemergency_withdraw(env, admin, token: Address, destination: Address), requiring (a) the contract to already be paused, (b) a timelocked confirmation (reusing the timelock queue from issue #2 if implemented, or a standalone 7-day delay) before execution, transferring the full token balance from contract custody to destination. Emits a prominent emergency_withdrawal_executed event.

Acceptance Criteria

  • Requires the contract to be paused first — cannot be called on an active contract
  • Requires a timelocked confirmation step separate from normal admin actions, with a minimum delay (e.g. 7 days) between request and execution
  • Transfers the entire current token balance held by the contract for the specified token to destination
  • emergency_withdrawal_executed event includes token, destination, and amount for maximum transparency
  • Test: withdrawal blocked while unpaused, blocked before timelock elapses, succeeds after pause + timelock with correct amount transferred
  • All existing cargo tests pass
  • cargo clippy passes with zero warnings

Metadata

Metadata

Assignees

No one assigned

    Labels

    complexity: highComplex feature requiring deep knowledge - 200 pts

    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