Skip to content
Open
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
112 changes: 112 additions & 0 deletions solutions/LP-0013.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Solution: LP-0013 — Token Program Improvements: Authorities

**Submitted by:** edenbd1

## Summary

Rotatable mint authority model for the LEZ Token program. Four additive instruction variants (`NewFungibleDefinitionWithAuthority`, `MintWithAuthority`, `RotateAuthority`, `RevokeAuthority`) layered on the existing token surface — pre-existing instructions and Borsh layout are untouched.

Built around `lez-approval` — a self-sufficient agnostic approval library fulfilling [RFP-001](https://github.com/logos-co/rfp/blob/master/RFPs/RFP-001-admin-authority-lib.md), [published on crates.io](https://crates.io/crates/lez-approval).

## Repository

- **Repo:** <https://github.com/edenbd1/lp-0013-token-authorities>
- **LEZ fork:** <https://github.com/edenbd1/logos-execution-zone/tree/lp-0013-token-authorities>
- **Narrated video:** <https://youtu.be/Um9cVHW226E>

## Approach

### Architecture

The authority model is layered **additively** — four new `Instruction` variants coexist with the seven originals. A new `TokenDefinition::FungibleWithAuthority` variant preserves full Borsh-layout backward compatibility (no breaking change to existing `Fungible` accounts).

Authority is verified **cryptographically** via the definition account's `is_authorized` flag (set by the NSSA runtime from the transaction signature) and an `account_id` match against the stored authority. The authority is never passed as spoofable instruction data.

### `lez-approval` (RFP-001)

Standalone crate with zero external dependencies beyond `borsh` and `serde`:
- `Authority(Option<[u8; 32]>)` — single-admin wrapper with terminal revocation
- `gate()` / `rotate()` / `revoke()` — the authorization contract
- `ApprovalError { Unauthorized, Renounced }` — documented panic payloads

The `config-pda-gate` example demonstrates the library gating a non-token program's privileged config updates (RFP-001 §4).

### Why the Logos stack

- **Trustless execution.** Every state transition is proved in a RISC0 guest — a renounced authority is provably renounced.
- **Censorship resistance.** Authority rotation is a standard transaction; the sequencer cannot selectively reject it.
- **Atomicity.** LEZ's per-account read-modify-write semantics guarantee no intermediate states.

### Alternatives considered

- **Separate authority PDA (Solana SPL pattern):** Rejected — doubles per-tx account count with no concurrency benefit on LEZ.
- **Modifying existing `Mint` instruction:** Rejected — breaking wire-format change. Additive variants are the correct LEZ idiom.
- **Authority as instruction data:** Rejected after discovering the spoofing vulnerability — switched to pre_state account verification.
- **`Result`-returning handlers:** Rejected — LEZ guest convention is panic-on-failure.

## Success Criteria Checklist

### Functionality

- [x] **Variable-size Tokens through minting authority:** `NewFungibleDefinitionWithAuthority` sets authority at init; `MintWithAuthority` gates minting; `RotateAuthority` rotates; `RevokeAuthority` permanently revokes.
- [x] **Three example integrations:** `examples/fixed-supply/`, `examples/variable-supply/`, `examples/config-pda-gate/` (RFP-001 §4 — gates non-token config PDA).
- [x] **Self-sufficient agnostic library per RFP-001:** `crates/lez-approval/` — [published on crates.io](https://crates.io/crates/lez-approval). 13 unit tests. Depends only on `borsh` + `serde`.

### Usability

- [x] **Module/SDK:** `crates/token-authority-sdk/` re-exports key types with transaction construction docs.
- [x] **IDL:** Two IDLs shipped — `artifacts/token.idl.json` (hand-authored, completeness) + `artifacts/token_authority.idl.spel.json` (real `spel -- generate-idl` output, provenance). Workaround rationale in `docs/SPEL_STATUS.md`.

### Reliability

- [x] **Atomic rotation/revocation:** Single field write or panic — no intermediate state.
- [x] **Deterministic rejection:** `ApprovalError::Renounced` with documented error code. Confirmed on-chain: `"Guest panicked: Renounced: authority has been permanently revoked"`.

### Performance

- [x] **CU costs documented:** Measured via `risc0_zkvm::default_executor` (5 samples, `risc0-zkvm 3.0.5`):
- `MintWithAuthority`: 166,746 cycles (+42% vs baseline `Mint`)
- `RotateAuthority`: 124,085 cycles (+6%)
- `RevokeAuthority`: 101,425 cycles (−14%)

### Supportability

- [x] **Deployed and tested:** Full lifecycle confirmed on standalone sequencer — create (supply=1000), mint 500 (supply=1500), revoke (nonce=3), post-revoke mint REJECTED.
- [x] **Integration tests:** 6 handler-pipeline tests + `scripts/demo.sh` for sequencer-level E2E.
- [x] **CI green:** [GitHub Actions](https://github.com/edenbd1/lp-0013-token-authorities/actions) — build, clippy, fmt, test.
- [x] **README:** Quickstart, architecture, CLI commands, deployment guide.
- [x] **Demo:** `scripts/demo.sh` — 4-step lifecycle against native standalone sequencer with `RISC0_DEV_MODE=0`.
- [x] **Narrated video:** <https://youtu.be/Um9cVHW226E>

## FURPS Self-Assessment

### Functionality
Four additive instruction variants. Pre-existing instructions unchanged. Regular `Mint` explicitly rejected on `FungibleWithAuthority` tokens. `Burn` works normally. Three token patterns supported: fixed supply, variable supply, governance handoff.

### Usability
SDK re-exports key types. CLI subcommands (`new-with-authority`, `mint-with-authority`, `rotate-authority`, `revoke-authority`) in the LEZ fork wallet. Dual IDL (hand-authored + SPEL-generated). `lez-approval` on crates.io — `lez-approval = "0.1"` to consume.

### Reliability
Authority state machine has three states (active, transitioning, revoked) with no intermediate or unreachable states. 72 tests across 4 crates + integration tests. Panic-on-failure matches LEZ guest convention.

### Performance
Authority check adds one `AccountId` equality comparison per gated instruction. `FungibleWithAuthority` adds 33 bytes per definition account.

### Supportability
72 tests. CI green. 9 documentation files. CONTRIBUTING.md, SECURITY.md, NOTICE. Criteria checklist maps every requirement to evidence.

## Supporting Materials

- **Repo:** <https://github.com/edenbd1/lp-0013-token-authorities>
- **LEZ fork:** <https://github.com/edenbd1/logos-execution-zone/tree/lp-0013-token-authorities>
- **crates.io:** <https://crates.io/crates/lez-approval>
- **Narrated video:** <https://youtu.be/Um9cVHW226E>
- **Architecture:** [`docs/architecture.md`](https://github.com/edenbd1/lp-0013-token-authorities/blob/main/docs/architecture.md)
- **Design decisions:** [`docs/design.md`](https://github.com/edenbd1/lp-0013-token-authorities/blob/main/docs/design.md)
- **CU benchmarks:** [`docs/benchmarks/cu-budget.md`](https://github.com/edenbd1/lp-0013-token-authorities/blob/main/docs/benchmarks/cu-budget.md)
- **SPEL disclosure:** [`docs/SPEL_STATUS.md`](https://github.com/edenbd1/lp-0013-token-authorities/blob/main/docs/SPEL_STATUS.md)
- **Demo script:** [`scripts/demo.sh`](https://github.com/edenbd1/lp-0013-token-authorities/blob/main/scripts/demo.sh)

## Terms & Conditions

By submitting this solution, I confirm that I have read and agree to the [Terms & Conditions](../TERMS.md).
Loading