Context & Problem Statement
The payment-distributor contract in contracts/payment-distributor/src/lib.rs stores a single static admin initialized at contract deployment. Transferring contract ownership directly in a single step introduces high risk of permanent lockout if a typo or incorrect address is passed.
This issue implements a secure two-step admin ownership transfer pattern (transfer_admin proposes a PendingAdmin, and the new address must call accept_admin to finalize), accompanied by comprehensive negative authorization unit tests.
Architectural Motivation & Technical Requirements
- In
contracts/payment-distributor/src/storage.rs:
- Add
StorageKey::PendingAdmin.
- Add
get_pending_admin, set_pending_admin, and clear_pending_admin storage helpers.
- In
contracts/payment-distributor/src/lib.rs:
- Implement
transfer_admin(env, current_admin: Address, new_admin: Address):
- Asserts
current_admin.require_auth().
- Writes
new_admin to PendingAdmin.
- Implement
accept_admin(env, new_admin: Address):
- Asserts
new_admin.require_auth().
- Validates
new_admin == get_pending_admin().
- Promotes
new_admin to Admin, clears PendingAdmin, and emits AdminTransferred event.
- In
contracts/payment-distributor/src/test.rs:
- Test successful two-step transfer.
- Test unauthorized caller on
transfer_admin.
- Test unauthorized caller on
accept_admin.
- Test chained transfers and event log emission.
Acceptance Criteria
Target Branch: dev
Estimated Effort: 5–12 hours | Delivery: 3–5 days
Difficulty: Medium
Context & Problem Statement
The
payment-distributorcontract incontracts/payment-distributor/src/lib.rsstores a single static admin initialized at contract deployment. Transferring contract ownership directly in a single step introduces high risk of permanent lockout if a typo or incorrect address is passed.This issue implements a secure two-step admin ownership transfer pattern (
transfer_adminproposes aPendingAdmin, and the new address must callaccept_adminto finalize), accompanied by comprehensive negative authorization unit tests.Architectural Motivation & Technical Requirements
contracts/payment-distributor/src/storage.rs:StorageKey::PendingAdmin.get_pending_admin,set_pending_admin, andclear_pending_adminstorage helpers.contracts/payment-distributor/src/lib.rs:transfer_admin(env, current_admin: Address, new_admin: Address):current_admin.require_auth().new_admintoPendingAdmin.accept_admin(env, new_admin: Address):new_admin.require_auth().new_admin == get_pending_admin().new_admintoAdmin, clearsPendingAdmin, and emitsAdminTransferredevent.contracts/payment-distributor/src/test.rs:transfer_admin.accept_admin.Acceptance Criteria
AdminTransferredevent emitted with previous and new admin addresses.Error::Unauthorized.cargo test -p payment-distributorpasses cleanly.Target Branch:
devEstimated Effort: 5–12 hours | Delivery: 3–5 days
Difficulty: Medium