diff --git a/solutions/LP-0013.md b/solutions/LP-0013.md new file mode 100644 index 0000000..67e1d4f --- /dev/null +++ b/solutions/LP-0013.md @@ -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).