Skip to content

feat: add deprecate_key and redeem for holder buybacks - #839

Merged
Chucks1093 merged 1 commit into
accesslayerorg:mainfrom
DammyAji:feat/834-key-deprecation-buyback
Sep 5, 2026
Merged

feat: add deprecate_key and redeem for holder buybacks#839
Chucks1093 merged 1 commit into
accesslayerorg:mainfrom
DammyAji:feat/834-key-deprecation-buyback

Conversation

@DammyAji

Copy link
Copy Markdown
Contributor

Summary

Closes #834

This PR implements an on-chain key deprecation mechanism that allows creators to sunset a key in an orderly way. When a creator calls deprecate_key, the key is permanently marked as deprecated, a fixed buyback price is set, and the total required payout (circulating_supply x buyback_price_per_key) is escrowed up-front. Holders can then call redeem at any time to exchange their entire balance for the fixed price.

Problem

Creators who wanted to wind down a key had no on-chain mechanism to do so gracefully. Once keys were minted, there was no supported path to disable further purchases or guarantee that holders could exit at a fair price.

Changes

creator-keys/src/lib.rs

New error variants (appended, never reordered per enum stability contract):

  • ContractError::KeyDeprecated = 54 - buy attempted on deprecated key
  • ContractError::InsufficientEscrow = 55 - creator underfunded the escrow

New DataKey variants (appended):

  • DeprecatedKey(Address) - marks key deprecated, stores buyback price
  • DeprecationEscrow(Address) - running escrow balance for redemptions

Guard in buy_key_with_referrer (covers both buy entrypoints):
Checks for DeprecatedKey immediately after pause/blacklist guards and returns KeyDeprecated before any price math.

deprecate_key(creator, caller, buyback_price_per_key, escrow_payment)

  • Only callable by creator (Unauthorized otherwise)
  • Requires buyback_price_per_key > 0; NotRegistered if creator absent
  • Rejects if already deprecated (KeyDeprecated)
  • Requires escrow_payment >= circulating_supply * buyback_price_per_key (InsufficientEscrow)
  • Writes DeprecatedKey and DeprecationEscrow to persistent storage
  • Emits KeyDeprecatedEvent

redeem(creator, holder)

  • Holder authorization required
  • Reads deprecation record; NotRegistered if key not deprecated
  • InsufficientBalance if holder has no keys
  • Burns all holder keys, decrements supply and holder_count
  • Deducts payout from escrow, transfers to holder
  • Emits KeysRedeemedEvent; returns payout amount

creator-keys/src/events.rs

  • KeyDeprecatedEvent with topics (key_dep, creator); fields: creator, buyback_price_per_key, circulating_supply, total_escrow, ledger
  • KeysRedeemedEvent with topics (key_rdm, creator, holder); fields: creator, holder, quantity, payout, new_supply, ledger

creator-keys/tests/key_deprecation.rs

14 integration tests covering all five acceptance criteria:

  1. Buy on deprecated key returns KeyDeprecated (AC1)
  2. Holder redeem receives correct payout (AC2)
  3. Insufficient escrow returns InsufficientEscrow (AC3)
  4. Non-creator returns Unauthorized (AC4)
  5. key_deprecated and keys_redeemed events emitted correctly (AC5)

Plus edge cases: double deprecation, multi-holder independent redemption, zero balance redeem, negative price guard, unregistered creator guard, referral path guard.

Checklist

  • Errors appended at end of ContractError (discriminants 54-55)
  • DataKey variants appended (no reordering)
  • Both buy entrypoints guarded
  • deprecate_key creator-only
  • redeem callable by any holder
  • Escrow exactly covers circulating_supply x buyback_price_per_key
  • key_deprecated event emitted
  • keys_redeemed event emitted
  • All five acceptance criteria covered by tests

@drips-wave

drips-wave Bot commented Aug 31, 2026

Copy link
Copy Markdown

@DammyAji 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

@DammyAji

DammyAji commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

hi @Chucks1093 please kindly review and merge. Thank you.

@Chucks1093

Copy link
Copy Markdown
Member

❌ CI Failed — verify (Contracts CI)

The verify check is failing on this PR.

Likely causes:

  • Compile error from an unresolved identifier or incorrect function signature
  • cargo fmt not run — CI detects formatting differences
  • Missing error variant in the contract error enum

Steps to fix:

  1. Run cargo build and fix all compiler errors
  2. Run cargo fmt --all and commit
  3. Push

@DammyAji

DammyAji commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

All checks have failed

1 failing check

failing checks

hi @Chucks1093 The verify ci failure is pre existing on main and not on this PR.

@Chucks1093

Copy link
Copy Markdown
Member

It has been resolved Rebase and Fix MC

@Chucks1093

Copy link
Copy Markdown
Member

Fix CI and MC

@DammyAji
DammyAji force-pushed the feat/834-key-deprecation-buyback branch from f4ac1ab to fb907ec Compare September 4, 2026 23:02
@Chucks1093

Copy link
Copy Markdown
Member

MC

…g#834)

- Add ContractError::KeyDeprecated (54) and InsufficientEscrow (55)
- Add DataKey::DeprecatedKey(Address) and DeprecationEscrow(Address)
- Guard buy_key_with_referrer to reject with KeyDeprecated on deprecated keys
- Add deprecate_key: creator-only, escrows supply*price, marks key deprecated
- Add redeem: holder exchanges all keys for buyback_price_per_key * quantity
- Emit KeyDeprecatedEvent on deprecate_key, KeysRedeemedEvent on redeem
- Add integration tests covering all five acceptance criteria

Closes accesslayerorg#834
@DammyAji
DammyAji force-pushed the feat/834-key-deprecation-buyback branch from afdc155 to 305635f Compare September 5, 2026 08:03
@Chucks1093
Chucks1093 merged commit 5ec99ba into accesslayerorg:main Sep 5, 2026
1 check passed
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 a key deprecation function allowing creators to sunset a key and trigger full holder buybacks at a fixed price

2 participants