Skip to content

feat(admin): add verify_admin_handover() helper with typed error#1678

Merged
Baskarayelu merged 2 commits into
QuickLendX:mainfrom
morelucks:feat/verify-admin-handover-1587
Jun 27, 2026
Merged

feat(admin): add verify_admin_handover() helper with typed error#1678
Baskarayelu merged 2 commits into
QuickLendX:mainfrom
morelucks:feat/verify-admin-handover-1587

Conversation

@morelucks

Copy link
Copy Markdown
Contributor

Summary

Implements issue #1587. Adds AdminStorage::verify_admin_handover(env, proposed) — a pure, read-only pre-flight guard that returns a typed OperationNotAllowed error when the proposed new admin address is identical to the current admin.

Motivation

Previously, callers had no clean way to detect a same-address handover before committing the full transfer_admin call. The only feedback was an ambiguous OperationNotAllowed that is also returned for other failure modes (uninitialized, transfer locked). This forced:

  • Frontend / off-chain clients to implement their own equality check.
  • Downstream contracts to attempt the transfer and handle a generic error.
  • Support to diagnose failures from opaque error codes.

verify_admin_handover provides one well-named entry point that makes the identity violation explicit and documentable.

Changes

quicklendx-contracts/src/admin.rs

New public function added to the second impl AdminStorage block:

pub fn verify_admin_handover(env: &Env, proposed: &Address) -> Result<(), QuickLendXError>
Condition Return
Admin not initialized Err(OperationNotAllowed)
proposed == current admin Err(OperationNotAllowed)
proposed != current admin Ok(())

The function is read-only: no storage writes, no auth calls, no events emitted.

quicklendx-contracts/src/test_admin_handover.rs (new)

9 deterministic tests covering:

  • proposed == current → error
  • proposed != current → ok
  • called before init → error
  • multiple unrelated addresses → all pass
  • idempotent: no state mutated (admin, lock, pending all unchanged)
  • transfer_admin self-transfer still rejected (no existing guard removed)
  • transfer_admin with valid candidate still succeeds (no regression)
  • two-step self-target still rejected
  • full two-step flow with valid candidate still works

quicklendx-contracts/src/lib.rs

Registered mod test_admin_handover with plain #[cfg(test)] — always-on, runs on every CI matrix entry.

docs/contracts/admin.md

New section documents the helper: purpose, signature, behaviour table, properties (read-only, idempotent, composable), usage example, and a note clarifying the helper is additive and does not remove existing guards.

Backwards compatibility

Fully backwards-compatible. The helper is additive. All existing transfer paths retain their own guards unchanged.

Testing

# New tests only (once pre-existing compile errors are resolved)
cargo test -p quicklendx-contracts test_admin_handover

# Full suite
cargo test -p quicklendx-contracts

# Lint
cargo clippy --workspace --all-targets -- -D warnings

# WASM verification
cargo build --target wasm32-unknown-unknown --release

Note: The codebase currently has 22 pre-existing compile errors in unrelated files (verification.rs, types.rs, lib.rs:3289, test_invoice_search_ranking.rs). None are introduced by this PR; they affect the full test suite and need a separate fix.

Closes #1587

morelucks and others added 2 commits June 26, 2026 17:45
…ckLendX#1587)

Adds AdminStorage::verify_admin_handover(env, proposed) — a pure,
read-only guard that returns Err(OperationNotAllowed) when proposed == current
admin, surfacing the identity violation as an explicit typed error without
requiring callers to attempt a full transfer and interpret an ambiguous
OperationNotAllowed from transfer_admin.

Changes:
- admin.rs: add verify_admin_handover() with doc-comment, behaviour table,
  and usage example; backed by existing is_initialized + get_admin helpers
- test_admin_handover.rs: 9 deterministic tests covering:
  - proposed == current → Err(OperationNotAllowed)
  - proposed != current → Ok(())
  - called before init   → Err(OperationNotAllowed)
  - multiple unrelated addresses all pass
  - idempotent/read-only: no state mutation, no pending admin, no lock
  - transfer_admin self-transfer regression (no existing guard removed)
  - transfer_admin with valid candidate still succeeds
  - two-step self-target still rejected
  - full two-step flow with valid candidate still works
- lib.rs: register test_admin_handover as always-on #[cfg(test)] module
- docs/contracts/admin.md: document the new helper with purpose, signature,
  behaviour table, and usage example

API is backwards-compatible: verify_admin_handover is additive;
transfer_admin and initiate_admin_transfer retain their own guards.

Closes QuickLendX#1587
@drips-wave

drips-wave Bot commented Jun 26, 2026

Copy link
Copy Markdown

@morelucks Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Baskarayelu

Copy link
Copy Markdown
Contributor

add verify_admin_handover() helper with typed error — nice work, merging 👍

@Baskarayelu Baskarayelu merged commit 70edefe into QuickLendX:main Jun 27, 2026
1 check failed
@grantfox-oss grantfox-oss Bot mentioned this pull request Jun 27, 2026
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add verify_admin_handover() helper

2 participants