Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions solutions/LP-0013.md
Original file line number Diff line number Diff line change
@@ -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:** <https://github.com/edenbd1/logos-execution-zone>
- **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<AccountId>)` — 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:** <https://github.com/edenbd1/logos-execution-zone/tree/lp-0013-token-authorities>
- **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).
Loading