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

**Submitted by:** bristinWild

## Summary

This submission implements a complete mint authority model for the LEZ Token program. Fungible tokens can now be created with a designated mint authority that can mint additional supply, rotate control to a new key, or permanently revoke minting to fix the supply. A standalone `lez-authority` crate provides the reusable authority primitive as defined in RFP-001.

## Demo Video
Link - https://www.youtube.com/watch?v=fJWbhobNIFM

## Repository

- **Repo:** https://github.com/bristinWild/logos-execution-zone
- **Branch:** `main`
- **Commit:** `da61c4fb`
- **Key files:**
- `lez-authority/src/lib.rs` — agnostic `AuthoritySlot` library (RFP-001)
- `programs/token/core/src/lib.rs` — `TokenDefinition::Fungible` with `mint_authority` field, `SetAuthority` and `NewFungibleDefinitionWithAuthority` instructions
- `programs/token/src/mint.rs` — authority-gated `Mint` handler
- `programs/token/src/set_authority.rs` — `SetAuthority` handler (rotation + revocation)
- `programs/token/src/new_definition.rs` — `NewFungibleDefinitionWithAuthority` handler
- `program_methods/guest/src/bin/token.rs` — guest binary dispatch for all new instructions
- `wallet/src/program_facades/token.rs` — `send_set_authority`, `send_new_definition_with_authority` SDK methods
- `integration_tests/tests/token.rs` — 2 integration tests for authority lifecycle
- `scripts/demo-full-flow.sh` — end-to-end demo script
- `scripts/examples/fixed_supply_token.sh` — fixed supply example
- `scripts/examples/variable_supply_token.sh` — variable supply + rotation example
- `docs/LP-0013-README.md` — architecture, usage, and design docs

## Approach

### Authority Model

`mint_authority: Option<[u8; 32]>` is added to `TokenDefinition::Fungible`:
- `Some(key)` — the key holder controls minting and can rotate/revoke
- `None` — supply is permanently fixed; minting is rejected deterministically

### `lez-authority` Crate (RFP-001)

A standalone crate with zero dependency on any specific program or `nssa_core`. Provides `AuthoritySlot` with `check()`, `set()` (rotate/revoke), and `is_revoked()`. All logic is unit-tested independently.

### New Instructions

| Instruction | Description |
|---|---|
| `NewFungibleDefinitionWithAuthority` | Create token with mint authority from day one |
| `Mint` (updated) | Now authority-gated — rejects if `mint_authority` is `None` |
| `SetAuthority` | Rotate to new key or revoke permanently (pass `None`) |

### Atomicity

`SetAuthority` only mutates `mint_authority` after all authorization checks pass. An unauthorized call returns an error before any write occurs — the prior authority is preserved. This is enforced structurally in `AuthoritySlot::set()`.

### SDK / Module

`wallet/src/program_facades/token.rs` exposes `send_set_authority` and `send_new_definition_with_authority` — typed async methods following the same pattern as all existing token facade methods.

## Success Criteria Checklist

- [x] **Variable-size tokens via mint authority** — `NewFungibleDefinitionWithAuthority` sets authority at init; `Mint` checks it
- [x] **Minting by the authority** — `Mint` handler validates `definition_account.is_authorized` + `mint_authority.is_some()`
- [x] **Authority rotation and revocation** — `SetAuthority` with `Some(new_key)` rotates; with `None` revokes permanently
- [x] **Two example integrations** — `scripts/examples/fixed_supply_token.sh` and `scripts/examples/variable_supply_token.sh`
- [x] **Self-sufficient agnostic authority library (RFP-001)** — `lez-authority` crate, zero deps on token program or nssa
- [x] **SDK/module** — `wallet/src/program_facades/token.rs` typed facade methods
- [x] **IDL** — token program uses `serde`-based instruction encoding (existing LEZ pattern); SPEL IDL generation available via `lgs spel -- generate-idl`
- [x] **Atomicity** — structural guarantee in `AuthoritySlot::set()`, verified by unit tests
- [x] **Deterministic rejection** — `"Mint authority has been revoked; this token has a fixed supply"` on every revoked-authority mint attempt
- [x] **CI green** — all 7 CI steps pass including `lez-authority` (7 tests) and `token_program` (42 tests)
- [x] **Integration tests** — 2 tests in `integration_tests/tests/token.rs` against live sequencer
- [x] **README** — `docs/LP-0013-README.md` with deployment steps, CLI instructions, architecture, error codes
- [x] **Demo script** — `scripts/demo-full-flow.sh`
- [ ] **CU costs** — TBD after devnet deployment
- [ ] **Recorded video demo** — TBD

## FURPS Self-Assessment

### Functionality
- `NewFungibleDefinitionWithAuthority`: creates fungible token with `mint_authority: Some(key)`
- `Mint`: checks `mint_authority.is_some()` before minting; deterministically panics if `None`
- `SetAuthority`: rotates to `Some(new_key)` or revokes to `None`; `is_authorized` check on definition account enforces caller identity
- Existing `NewFungibleDefinition` creates tokens with `mint_authority: None` (fixed supply by default — backward compatible)
- All existing 34 token tests continue to pass unchanged

### Usability
- Single new field on `TokenDefinition::Fungible` — minimal diff, easy to audit
- `lez-authority` crate is importable by any LEZ program without token program dependency
- Wallet facade methods follow existing async pattern exactly
- `docs/LP-0013-README.md` documents all flows with CLI examples

### Reliability
- Atomicity: `AuthoritySlot::set()` returns `Err` before mutating — no partial writes possible
- 8 dedicated authority unit tests cover: mint success, mint with wrong authority, mint after revocation, rotation, revocation permanence, double-revoke, unauthorized rotation, state-unchanged-on-error
- All 42 `token_program` tests pass; all 7 `lez-authority` tests pass

### Performance
- Authority check in `Mint`: single `Option` match — negligible CU overhead
- `SetAuthority`: single account read + write — same CU profile as existing `Burn`
- CU costs will be documented after devnet deployment

### Supportability
- CI updated with dedicated LP-0013 test steps — green on every push
- `scripts/demo-full-flow.sh` reproducible against local sequencer
- `docs/LP-0013-README.md` documents deployment, CLI usage, architecture, error codes
- Rebased onto upstream HEAD (4079b0c9) — fully current with LEZ codebase

## Supporting Materials

- **Architecture docs:** [`docs/LP-0013-README.md`](https://github.com/bristinWild/logos-execution-zone/blob/main/docs/LP-0013-README.md)
- **Authority library:** [`lez-authority/src/lib.rs`](https://github.com/bristinWild/logos-execution-zone/blob/main/lez-authority/src/lib.rs)
- **SetAuthority handler:** [`programs/token/src/set_authority.rs`](https://github.com/bristinWild/logos-execution-zone/blob/main/programs/token/src/set_authority.rs)
- **Mint handler (updated):** [`programs/token/src/mint.rs`](https://github.com/bristinWild/logos-execution-zone/blob/main/programs/token/src/mint.rs)
- **Token core (updated):** [`programs/token/core/src/lib.rs`](https://github.com/bristinWild/logos-execution-zone/blob/main/programs/token/core/src/lib.rs)
- **Demo script:** [`scripts/demo-full-flow.sh`](https://github.com/bristinWild/logos-execution-zone/blob/main/scripts/demo-full-flow.sh)
- **Example scripts:** [`scripts/examples/`](https://github.com/bristinWild/logos-execution-zone/tree/main/scripts/examples)
- **CI:** https://github.com/bristinWild/logos-execution-zone/actions

## Terms & Conditions

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