Skip to content

[Feature] Admin self-service emergency controls (manual pause/resume and emergency_withdraw) with SEP-53 signature proof #263

Description

@Sendi0011

Summary

The Soroban contracts expose high-stakes admin primitives — rotational::pause, unpause, and emergency_withdraw — but there is no admin-facing UI to invoke any of them directly. Today the only path that ever pauses a pool is the automatic security circuit breaker (PR #259); a pool admin has no self-service way to manually pause a pool, resume it on-chain, or trigger an emergency_withdraw if a contract malfunctions.

Compare this to the archive flow, which was hardened in PR #259: it got a proper wallet-signature proof (lib/archive-proof.ts + lib/server/wallet-proof.ts) and a UI banner. Pool pause/resume/emergency withdraw need the same treatment — these actions move or halt money and must not be callable by an address stuck in a request body.

Requirements

  1. Manual pause / resume UI in the pool group page for the pool admin: pause with a reason and resume, mirroring archived-pool-banner.tsx styling. The platform pause flips pools.status (reuse pause_reason/paused_at columns added in PR feat(security): automated incident response and on-chain circuit breaker for critical pool alerts #259); the on-chain pause/unpause is a contract call signed by the admin's own wallet.
  2. Emergency withdrawal UI (admin-only): a deliberate, clearly-labelled flow to call rotational::emergency_withdraw(admin, recipient) that (a) shows exactly what it will do and the recipient address, (b) requires a confirmation step, and (c) is signed by the admin's wallet.
  3. SEP-53 signature proof (mirror the archive hardening): do NOT trust callerAddress/admin_address in the request body. The admin wallet signs a short timestamped message (via wallet-proof/signMessage) naming the pool and the exact action, and the server verifies it against the pool's recorded creator_address before committing. Reuse checkWalletProof / verifySignedMessage in frontend/lib/server/wallet-proof.ts.
  4. Server endpoints (or extend the existing admin route) that verify ownership, the signature proof, the 64-char tx hash, and then record the action in pool_activity so it shows in the admin audit log — mirroring the /api/pools/[id]/archive and /api/admin/incidents/[id] (record_onchain) patterns.
  5. Safeguards: emergency withdraw should refuse when the pool is not active/paused-eligible, should be rate-limited, and should clearly warn that it is irreversible. Add EN + ES strings.

Notes / context

  • The contract functions already exist — rotational/src/lib.rs has pause, unpause, emergency_withdraw. This issue is about the safe, provable UI + API layer, not changing the contracts.
  • Follow the archive hardening exactly: frontend/lib/archive-proof.ts (client signing), frontend/lib/server/wallet-proof.ts (verification), and the archived-pool-banner.tsx component conventions.
  • Emergency withdraw is a funds-moving admin action and must remain strictly manual and admin-only — never reachable from any automated path (the incident-response breaker already enforces this; keep it that way).
  • Component tests using Vitest + RTL, following frontend/__tests__/deposit-calendar.test.tsx conventions, would strengthen this.

Acceptance criteria

  • Admin can manually pause/resume a pool from the UI with a reason, and call emergency_withdraw through a confirmed, signed flow
  • Every action requires a fresh SEP-53 wallet signature verified against the pool's creator_address (spoofing admin_address gets nowhere)
  • On-chain submissions record the 64-char tx hash and appear in the admin audit log
  • Guardrails: eligibility checks, rate limiting, irreversible-action warning, EN + ES strings
  • Component + unit tests cover the signature proof, ownership checks, and the action flow
  • Lint, format, and all CI checks pass

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardThird CampaignCampaign: Third CampaignfeatureNew functionality to addfrontendhigh-complexityLarge scope, multiple systems/files. Needs planningpriority: highMajor impact, breaks key feature. fix next after P0smart-contract

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions