diff --git a/solutions/LP-0013.md b/solutions/LP-0013.md new file mode 100644 index 0000000..0921894 --- /dev/null +++ b/solutions/LP-0013.md @@ -0,0 +1,132 @@ +# 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=Q_uAv7xRD-c + +## Repository + +- **Repo:** https://github.com/bristinWild/lez-programs (PR: https://github.com/logos-blockchain/lez-programs/pull/125) +- **Fork:** https://github.com/bristinWild/lez-programs +- **Branch:** `solution/lp-0013-authorities` +- **Commit:** `c2d259e` +- **Key files:** + - `lez-authority/src/lib.rs` — `Authority` type + `Ownable` trait (RFP-001) + - `programs/token/core/src/lib.rs` — `TokenDefinition::Fungible` with `authority: Authority` field + - `programs/token/src/mint.rs` — authority-gated `Mint` handler (self/external authority) + - `programs/token/src/set_authority.rs` — `SetAuthority` handler (rotation + revocation) + - `programs/token/src/new_definition.rs` — `NewFungibleDefinition` with `mint_authority: Option` + - `programs/token/methods/guest/src/bin/token.rs` — guest binary dispatch for all instructions + - `programs/integration_tests/tests/token.rs` — 17 integration tests including full rotation flow + - `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, CU costs, CLI usage, design docs + - `artifacts/token-idl.json` — regenerated IDL via SPEL framework + +## Approach + +### Authority Model + +`authority: Authority` is embedded directly in `TokenDefinition::Fungible` via the `lez-authority` crate: +- `Authority(Some(key))` — the key holder controls minting and can rotate/revoke +- `Authority(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: +- `Authority(Option<[u8; 32]>)` newtype with `authority()`, `require()`, `rotate()` +- `Ownable` trait with `require_owner`, `transfer_ownership`, `renounce_ownership` + +All logic is unit-tested independently (8 tests). + +### Instructions + +| Instruction | Description | +|---|---| +| `NewFungibleDefinition` | Create token with optional mint authority (`mint_authority: Option`) | +| `Mint` (updated) | Authority-gated — self-authority (empty rest accounts) or external rotated authority (rest account) | +| `SetAuthority` | Rotate to new key (`Some(key)`) or revoke permanently (`None`) | + +### Authority Transfer (RFP-001) + +The `Mint` and `SetAuthority` instructions support both self/PDA authority and external rotated authority passed as a rest account. After rotation, the new key can actually mint — proven by the `token_rotate_authority_then_new_authority_can_mint` integration test. + +### Atomicity + +`SetAuthority` only mutates `authority` after all authorization checks pass. Unauthorized calls return before any write — prior authority is preserved. Structural guarantee via `Authority::rotate()`. + +## Success Criteria Checklist + +- [x] **Variable-size tokens via mint authority** — `NewFungibleDefinition` sets authority at init; `Mint` checks it +- [x] **Minting by the authority** — self-authority and external rotated-authority paths both supported and tested +- [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** — SPEL IDL + CLI integration; guest binary wired for all instructions +- [x] **IDL** — `artifacts/token-idl.json` regenerated via SPEL framework +- [x] **Atomicity** — structural guarantee in `Authority::rotate()`, verified by unit tests +- [x] **Deterministic rejection** — `"Mint authority check failed: Revoked"` on every revoked-authority mint attempt +- [x] **CU costs** — measured from LEZ sequencer execution logs on localnet: + `NewFungibleDefinition` ~11ms, `Mint` ~10ms, `SetAuthority` ~8ms (execution time + inside zkVM, measured via sequencer logs with `RISC0_DEV_MODE=1`; this reflects + actual program execution cost independent of proof generation). Full ZK proof + generation takes 3–10 minutes per tx with `RISC0_DEV_MODE=0` on Apple M-series + hardware. LEZ devnet/testnet deployment pending public sequencer availability. +- [x] **Integration tests** — 17 tests in `programs/integration_tests/tests/token.rs` against live sequencer (standalone mode), including full RFP-001 rotation flow +- [x] **CI green** — 60 unit tests + 17 integration tests passing +- [x] **README** — `docs/LP-0013-README.md` with deployment steps, CLI instructions, architecture, error codes +- [x] **Demo script** — `scripts/demo-full-flow.sh` — reproducible against local LEZ sequencer with `RISC0_DEV_MODE=0` +- [x] **Recorded video demo** — https://www.youtube.com/watch?v=Q_uAv7xRD-c (narrated, `RISC0_DEV_MODE=0` terminal output visible) + +## FURPS Self-Assessment + +### Functionality +- `NewFungibleDefinition`: creates fungible token with `mint_authority: Option` — `Some` = mintable, `None` = fixed supply +- `Mint`: self-authority (definition account is its own authority) or external rotated authority (rest account) +- `SetAuthority`: rotates to `Some(new_key)` or revokes to `None`; authorization check enforces caller identity +- Metadata fungibles carry a real `mint_authority` — intentional and tested +- AMM LP token authority correctly wired to pool PDA — all AMM tests pass unchanged + +### Usability +- Single embedded `authority: Authority` field — minimal diff, easy to audit +- `lez-authority` importable by any LEZ program without token program dependency +- `artifacts/token-idl.json` enables full SPEL CLI interaction +- `docs/LP-0013-README.md` documents all flows with CLI examples and CU costs + +### Reliability +- Atomicity: `Authority::rotate()` returns `Err` before mutating — no partial writes possible +- 13 dedicated authority unit tests cover all lifecycle cases +- 17 integration tests including full rotation flow at executor level +- All 60 unit tests + 17 integration tests pass + +### Performance +- Authority check in `Mint`: single `Option` match — negligible overhead +- `SetAuthority`: single account read + write +- CU costs (LEZ localnet, `RISC0_DEV_MODE=1`): `NewFungibleDefinition` ~11ms, `Mint` ~10ms, `SetAuthority` ~8ms + +### Supportability +- Demo script reproducible against local sequencer with `RISC0_DEV_MODE=0` +- `docs/LP-0013-README.md` documents deployment, CLI usage, architecture, error codes +- PR #125 on `logos-blockchain/lez-programs` — rebased onto upstream main + +## Supporting Materials + +- **PR:** https://github.com/logos-blockchain/lez-programs/pull/125 +- **Architecture docs:** `docs/LP-0013-README.md` +- **Authority library:** `lez-authority/src/lib.rs` +- **SetAuthority handler:** `programs/token/src/set_authority.rs` +- **Mint handler:** `programs/token/src/mint.rs` +- **Demo script:** `scripts/demo-full-flow.sh` +- **Example scripts:** `scripts/examples/` +- **Demo video:** https://www.youtube.com/watch?v=Q_uAv7xRD-c + +## Terms & Conditions + +By submitting this solution, I confirm that I have read and agree to the [Terms & Conditions](../TERMS.md).