diff --git a/solutions/LP-0013.md b/solutions/LP-0013.md new file mode 100644 index 0000000..9cf8b0d --- /dev/null +++ b/solutions/LP-0013.md @@ -0,0 +1,122 @@ +# Solution: LP-0013 — Token Program Improvements: Authorities + +**Submitted by:** edenbd1 + +## Summary + +This solution adds a rotatable mint authority model to the LEZ Token program. The implementation is built around `lez-approval` — a new agnostic single-admin approval crate that fulfils [RFP-001](https://github.com/logos-co/rfp/blob/master/RFPs/RFP-001-admin-authority-lib.md) — and exposes four new instruction variants (`NewFungibleDefinitionWithAuthority`, `MintWithAuthority`, `RotateAuthority`, `RevokeAuthority`) layered additively over the existing Token surface. Revocation is terminal — once revoked, no instruction can re-introduce an authority. All pre-existing instructions remain untouched and fully backward-compatible. + +## Repository + +- **Repo:** +- **Branch:** `lp-0013-token-authorities` +- **Commit:** [`d59379e`](https://github.com/edenbd1/logos-execution-zone/commit/d59379e) +- **Key files:** + - `lez-approval/src/lib.rs` — RFP-001 agnostic approval library (`Authority`, `ApprovalError`) + - `programs/token/core/src/lib.rs` — `Instruction` enum extensions and `FungibleWithAuthority` variant on `TokenDefinition` + - `programs/token/src/authority.rs` — handler implementations for all four authority instructions + - `program_methods/guest/src/bin/token.rs` — guest dispatcher updated with new instruction arms + - `wallet/src/program_facades/token.rs` — wallet facade with typed builders + - `wallet/src/cli/programs/token.rs` — CLI subcommands (`new-with-authority`, `mint-with-authority`, `rotate-authority`, `revoke-authority`) + - `examples/token_authority/` — two example scripts (fixed-supply, variable-supply) + - `integration_tests/tests/token_authority.rs` — five end-to-end lifecycle tests + - `artifacts/token.idl.json` — hand-authored canonical IDL conforming to `SpelIdl` + - `docs/LP-0013-AUTHORITY.md` — architecture, CLI usage, error codes + - `demo.sh` — clean-checkout end-to-end demo (create → mint → rotate → mint → revoke → verify rejection) + +## Approach + +### Architecture + +The Token program already had `Mint`, `Transfer`, `NewFungibleDefinition`, etc. as variants of a single `Instruction` enum dispatched by `program_methods/guest/src/bin/token.rs`. We layer the authority model **additively**: four new instruction variants coexist with the existing surface. Pre-existing paths are untouched, so naïve callers continue to work. + +State-wise, the authority is recorded as a new `FungibleWithAuthority` variant of `TokenDefinition` with an `authority: Authority` field. We chose a new enum variant rather than modifying the existing `Fungible` variant to preserve complete Borsh-layout compatibility with pre-existing definitions. + +### `lez-approval` as the RFP-001 deliverable + +The agnostic approval library is implemented as a new top-level workspace crate, `lez-approval`. It exposes: + +- `Authority(Option)` — a single-admin wrapper whose `None` state is terminal (renounced). The `Option` is hidden behind constructors and predicates. +- `ApprovalError { Unauthorized, Renounced }` — two-variant error type surfaced as panic payloads. +- `gate` / `rotate` / `revoke` — the authorization contract. + +The crate depends only on `nssa_core::account::AccountId` and is reusable by any LEZ program that wants single-admin gating. + +### Why the Logos stack + +- **Trustless execution.** Every state transition is proved in a RISC0 guest, so a renounced authority is provably renounced — no off-chain admin key can secretly revive it. +- **Censorship resistance.** Authority rotation is just another transaction; the sequencer cannot selectively reject it. +- **Atomicity.** LEZ's per-account read-modify-write semantics give us atomic rotation/revocation with no intermediate states. + +### Alternatives considered + +- **Separate authority PDA (Solana SPL pattern).** Rejected — doubles per-tx account count with no concurrency benefit on LEZ. +- **In-place mutation of `Instruction::Mint`.** Rejected — breaking wire-format change that would invalidate existing callers. +- **`Result`-returning handlers.** Rejected — LEZ guest convention is panic-on-failure; mixing styles is a maintenance trap. + +## Success Criteria Checklist + +### Functionality + +- [x] **Variable-size Tokens through minting authority:** `NewFungibleDefinitionWithAuthority` sets authority at init; `MintWithAuthority` mints gated by the authority; `RotateAuthority` rotates; `RevokeAuthority` permanently revokes (set to `None`). +- [x] **Two example integrations:** `examples/token_authority/fixed_supply.sh` (mint then revoke) and `examples/token_authority/variable_supply.sh` (rotatable authority with ongoing minting). +- [x] **Self-sufficient agnostic library per RFP-001:** `lez-approval/` ships `Authority`, `ApprovalError`, and `gate`/`rotate`/`revoke`. Depends only on `nssa_core::account::AccountId`. + +### Usability + +- [x] **Module/SDK for Logos modules:** `wallet/src/program_facades/token.rs` exposes typed builders for all four new instructions; `wallet/src/cli/programs/token.rs` wires them as CLI subcommands. +- [x] **IDL for the updated token program:** `artifacts/token.idl.json` — hand-authored canonical IDL conforming to `SpelIdl`, including the new instructions, `FungibleWithAuthority` account type, `Authority` struct, and `ApprovalError` error codes. + +### Reliability + +- [x] **Atomic rotation/revocation:** Both handlers perform a single field write or panic. No intermediate state exists — `rotate` atomically replaces the admin, `revoke` atomically sets to `None`. +- [x] **Deterministic rejection:** `MintWithAuthority` against a revoked authority panics with `ApprovalError::Renounced`. Against a wrong signer, panics with `ApprovalError::Unauthorized`. Both are documented error variants. + +### Performance + +- [x] **CU cost documentation:** The three new instructions add one `is_authorized` check and one `AccountId` equality check per gated call. Overhead is negligible relative to baseline `Mint`. + +### Supportability + +- [x] **Deployed and tested on LEZ sequencer:** `demo.sh` runs the full lifecycle against a docker-compose standalone LEZ sequencer. +- [x] **End-to-end integration tests in CI:** `integration_tests/tests/token_authority.rs` — five test cases covering create, mint, rotate, revoke, and rejection paths. +- [x] **CI green on default branch:** `cargo clippy --all-targets -- -D warnings` and `cargo fmt --check` clean. 57 unit tests pass (13 lez-approval + 44 token_program). +- [x] **README documents end-to-end usage:** `docs/LP-0013-AUTHORITY.md` covers architecture, CLI commands, error codes, and step-by-step workflows. +- [x] **Reproducible demo with `RISC0_DEV_MODE=0`:** `demo.sh` runs the full create → mint → rotate → mint → revoke → verify-rejection lifecycle. +- [ ] **Narrated video walkthrough:** Pending. + +## FURPS Self-Assessment + +### Functionality + +Four new instruction variants (`NewFungibleDefinitionWithAuthority`, `MintWithAuthority`, `RotateAuthority`, `RevokeAuthority`). Pre-existing instructions are unchanged. The authority model supports fixed supply (mint then revoke), variable supply (active authority), and authority handoff (rotate). Revocation is terminal. + +### Usability + +Wallet SDK exposes typed facade methods. CLI subcommands mirror the existing Token-program subcommand idiom. No new flags or env vars beyond the existing wallet setup. + +### Reliability + +The single-admin state machine has three states (active, transitioning, revoked) with no intermediate or unreachable states. Panic-on-failure semantics match the LEZ guest convention. 57 unit tests + 5 integration tests cover all paths. + +### Performance + +The authority check adds negligible overhead (one `AccountId` equality comparison) per gated instruction relative to the baseline `Mint`. The `FungibleWithAuthority` variant adds 33 bytes (1 discriminant + 32 `AccountId`) to the on-chain definition account. + +### Supportability + +- **Test coverage:** 13 `lez-approval` unit tests + 44 `token_program` unit tests (10 new authority tests) + 5 integration tests = 62 total tests. +- **Code structure:** Authority logic split between the generic `lez-approval/` crate (reusable) and the Token-specific handlers in `programs/token/src/authority.rs`. +- **Demo:** `demo.sh` is the canonical end-to-end deployment and exercise script. + +## Supporting Materials + +- **Companion repo:** +- **Architecture doc:** [`docs/LP-0013-AUTHORITY.md`](https://github.com/edenbd1/logos-execution-zone/blob/lp-0013-token-authorities/docs/LP-0013-AUTHORITY.md) +- **IDL:** [`artifacts/token.idl.json`](https://github.com/edenbd1/logos-execution-zone/blob/lp-0013-token-authorities/artifacts/token.idl.json) +- **Demo script:** [`demo.sh`](https://github.com/edenbd1/logos-execution-zone/blob/lp-0013-token-authorities/demo.sh) +- **Narrated video:** _pending_ + +## Terms & Conditions + +By submitting this solution, I confirm that I have read and agree to the [Terms & Conditions](../TERMS.md).