Description
Contract admins have no mechanism to block bad actors (sanctioned addresses, fraudulent payers) from interacting with any invoice. This issue adds an admin-managed payer blacklist with a built-in appeal window during which a blacklisted address can submit an appeal hash and admins can review before the ban is finalised.
Technical Context
Add blacklist_key(payer: Address) -> Symbol storing BlacklistEntry { banned_at: u64, appeal_hash: Option<BytesN<32>>, finalised: bool } in types.rs and lib.rs. Admin calls blacklist_payer(env, admin, payer, reason_hash: BytesN<32>). Payer calls submit_appeal(env, payer, invoice_id, appeal_hash: BytesN<32>) within APPEAL_WINDOW_LEDGERS. Admin calls finalise_blacklist(env, admin, payer, uphold: bool). pay_invoice checks finalised && !uphold → panic PayerBlacklisted.
Acceptance Criteria
Description
Contract admins have no mechanism to block bad actors (sanctioned addresses, fraudulent payers) from interacting with any invoice. This issue adds an admin-managed payer blacklist with a built-in appeal window during which a blacklisted address can submit an appeal hash and admins can review before the ban is finalised.
Technical Context
Add
blacklist_key(payer: Address) -> SymbolstoringBlacklistEntry { banned_at: u64, appeal_hash: Option<BytesN<32>>, finalised: bool }intypes.rsandlib.rs. Admin callsblacklist_payer(env, admin, payer, reason_hash: BytesN<32>). Payer callssubmit_appeal(env, payer, invoice_id, appeal_hash: BytesN<32>)withinAPPEAL_WINDOW_LEDGERS. Admin callsfinalise_blacklist(env, admin, payer, uphold: bool).pay_invoicechecksfinalised && !uphold→ panicPayerBlacklisted.Acceptance Criteria
blacklist_payerrecords entry withfinalised: false; only admin can call itpay_invoiceblocks finalised-blacklisted payers withPayerBlacklistedAPPEAL_WINDOW_LEDGERSwindowuphold: true(ban stands) orfalse(payer reinstated)PayerBlacklisted,AppealSubmitted,BlacklistFinalisedevents emitted fromevents.rs