diff --git a/solutions/LP-0013.md b/solutions/LP-0013.md new file mode 100644 index 0000000..d006820 --- /dev/null +++ b/solutions/LP-0013.md @@ -0,0 +1,174 @@ +# Solution: LP-0013 — Token program improvements: authorities + +**Submitted by:** Tranquil-Flow + +## Summary + +This submission implements a mint-authority lifecycle for LEZ tokens: variable-supply minting by an authority, atomic authority rotation, permanent revocation to `None` for fixed-supply tokens, deterministic post-revocation rejection, SDK/CLI support, examples, and IDL artifacts. + +The corrected LEZ guest is deployed and exercised on the current public LEZ testnet (`https://testnet.lez.logos.co/`, real consensus, `RISC0_DEV_MODE=0`). The load-bearing 2026-06-27 v0.2.0 lifecycle proves the reviewer-critical fix: two mints to the same holding account both confirm and accumulate (`60 + 40 = 100`), then a post-revocation mint to that already-existing holding is rejected by the authority guard rather than by an account-initialization side effect. + +## Repository + +Public repository: + +```text +https://github.com/Tranquil-Flow/lp0013-token-suite +``` + +**License:** MIT OR Apache-2.0 + +## Approach + +The implementation splits the token-authority surface into reusable library and LEZ-facing layers: + +1. `mint-core` and `admin-authority-core` define mint state, authority state, deterministic errors, and offline contract tests. +2. `mint-program` implements the corrected four-instruction LEZ guest surface: `create_mint`, `create_holding`, `mint_to`, and `set_mint_authority`. +3. `mint-sdk`, `mint-cli`, and `onchain-program/examples` provide SDK/client flows for Logos-module interactions and live LEZ lifecycle execution. +4. `idl/` contains SPEL-generated IDL artifacts for the deployed four-instruction surface; the hand-written IDL is retained only as a caveated design reference. +5. `examples/` includes fixed-supply, variable-supply, and config-PDA-gated integrations. +6. `scripts/demo-localnet.sh`, `scripts/preflight-localnet-e2e.sh`, `scripts/demo-testnet-live.sh`, and `scripts/ci-verify-testnet.sh` provide reproducible localnet and public-testnet verification paths. + +## Public-testnet evidence + +> **Current refresh status (2026-06-27):** reviewer `xAlisher` asked for a fresh redeploy/re-anchor because Logos reset `testnet.lez.logos.co` after this PR was submitted. That refresh is now complete on the current public testnet using the LEZ v0.2.0 client/runtime path: the corrected release RISC Zero guest was wrapped as a `risc0_binfmt::ProgramBinary` (`sha256 fac6f9715efc03edcb695dc71545cb24fac6bc86530644e2748f50d6ef9009f3`), deployed, and exercised through the full lifecycle. All positive lifecycle transactions are included, the post-revoke mint is not included as expected, and final state reads back `authority=None`, `supply=100`, `decimals=6`, holding `balance=100`. The implementation repo tracks details in `docs/CURRENT_TESTNET_REFRESH.md` and `docs/LEZ_PROOF_LOG.md`. + +Network: `https://testnet.lez.logos.co/` + +ProgramId / ImageID: + +```text +338865e9549b18fb736020eaef87d5e20075b4250e10c00e08ea918c4871554a +``` + +Explorer-form base58 ProgramId: + +```text +4UARaVcJJoLxebFAobocsZyzpJ5TTUvvhRtFuHtuHypd +``` + +Canonical lifecycle: + +| Step | Transaction hash | Verdict | +|---|---|---| +| deploy_program | `793992258d88e69c63cbede6fabec3ff5768d84d824d7ee9f3170f85fb717dce` | `Some(ProgramDeployment)` | +| create_mint | `55908821088c98e898c4ef99e9a36e02856092f7afd0155f3457c25c5cf67746` | `Some(Public)` | +| create_holding | `8a37a8fb7200856c57d199ce081f2b744ed3cbaeec8326c83092f5ca05ac668f` | `Some(Public)` | +| mint_to(60) | `daf5aa91f35dff8250794c0dcfe932de473c651bd25c946d76f09a42cfdb6a97` | `Some(Public)` | +| mint_to(40) | `ed07b29c004a796d504814ddf1a9a0cfda373d1618398b620e330ccb529b3cce` | `Some(Public)` | +| set_mint_authority(None) | `719123f918df2aee42c4e69d36ba8860807b2a69c97a2927097d8313a508550e` | `Some(Public)` | +| mint_to(post-revoke) | `016043771c0cc60efaf158ec120a9bf341326967c881285878469503ddd3d4fa` | not included (`Transaction is None`) | + +Final state read from chain: + +- mint PDA `4gMBXeUskbUTzxoP8fJJEXj3jxTQz91m6ZW7fMsLMJq6`: `authority=None`, `supply=100`, `decimals=6` +- holding PDA `366n7Nj21EzD27BXRKE2hFDWPtJ1E2Fcx9RmqQoGRD7h`: `balance=100` +- signer / authority: `6HEYFUW4QbHPfdHTMPZLDeC6F5PL6suhSGJbTnsauhWJ` + +Read-only re-verification: + +```bash +bash scripts/demo-testnet-live.sh verify +``` + +Full requirements matrix: `docs/LP0013_REQUIREMENTS_MATRIX.md` in the implementation repository. + +If `wallet` is unavailable, build it from the LEZ v0.2.0 source tree as described in the implementation repository docs (`docs/LEZ_PROOF_LOG.md` and `onchain-program/README.md`). + +## What was fixed after the previous review + +The rejected build used `#[account(init, pda)]` on the recipient holding account inside `mint_to`. That meant: + +1. a second mint to the same holding failed because `init` rejected the already-claimed account; and +2. the post-revocation mint was rejected before the authority guard ran, so it did not prove revoked-authority enforcement. + +The corrected guest splits holding creation from minting: + +- `create_holding(#[account(init, pda)] holding, #[account(signer)] payer)` claims the holding once. +- `mint_to(#[account(mut, pda)] mint, #[account(mut, pda)] recipient_holding, #[account(signer)] authority, amount)` mutates an existing holding and performs `require_authority` before any state change. + +The public-testnet lifecycle above demonstrates this distinction on chain: both mints land into the same holding, then the post-revocation mint targets the same existing holding and is rejected by the authority guard. + +## Success Criteria Checklist + +### Functionality + +- [x] Variable-size tokens through minting authority. +- [x] Mint authority set at token initialization. +- [x] Minting by the authority, with repeated mints to the same holding account (`60 + 40 = 100`) verified on the public testnet. +- [x] Authority rotation and permanent revocation to `None`. +- [x] Fixed-supply behavior after revocation: post-revocation mint is rejected and supply remains `100`. +- [x] Deterministic revoked-authority rejection through the authority guard, not an account-init side effect. + +### Usability + +- [x] SDK/module support through `mint-sdk`, `mint-cli`, and `onchain-program/examples`. +- [x] At least two example integrations: fixed-supply, variable-supply, and config-PDA-gated examples are included. +- [x] SPEL-generated IDL artifacts are included under `idl/`. +- [x] README and spec-compliance docs explain build, localnet, and public-testnet verification commands. + +### Reliability + +- [x] Contract tests cover repeated minting to the same holding and post-revocation guard rejection. +- [x] Offline workspace tests and validator self-tests run in CI. +- [x] Current public-testnet evidence can be re-queried read-only after the Logos-side testnet reset. The 2026-06-27 v0.2.0 refresh re-confirms deploy, create_mint, create_holding, two mints, revocation, post-revoke non-inclusion, and final account state. +- [x] Standalone local-sequencer e2e is included in CI config via hosted preflight plus manual self-hosted prepared-run job, and a real `RISC0_DEV_MODE=0` prepared-host run passed on 2026-06-09. + +### Performance + +- [x] CU methodology and platform limitation are documented in `docs/BENCHMARKS.md`. +- [x] The public testnet does not expose per-transaction CU, so the repository avoids inventing chain-native CU numbers and labels local sequencer/executor measurements honestly. + +### Supportability + +- [x] Deployable guest source lives in the repository under `onchain-program/`. +- [x] Current public-testnet lifecycle tx hashes after reset. The 2026-06-27 v0.2.0 refresh provides fresh deploy, create_mint, create_holding, mint_to(60), mint_to(40), set_mint_authority(None), and post-revoke non-inclusion hashes. +- [x] `scripts/demo-localnet.sh` supports standalone local-sequencer reproduction under `RISC0_DEV_MODE=0`. +- [x] `.github/workflows/ci.yml` includes `local-sequencer-e2e-preflight` and manual `local-sequencer-e2e`. +- [x] `scripts/demo-testnet-live.sh verify` and `scripts/ci-verify-testnet.sh` support current RPC method names and fail-closed public-testnet re-verification. +- [x] Fresh narrated demo video recorded and linked: https://youtu.be/rUgsCCPiQfo + +## Local verification commands + +```bash +cargo fmt --all -- --check +cargo check --workspace +cargo test --workspace +cargo clippy --workspace --all-targets -- -D warnings +python3 scripts/validate-submission-docs.py +python3 -m pytest tests/test_validate_submission_docs.py -q +``` + +## Video status + +Fresh narrated demo video: https://youtu.be/rUgsCCPiQfo. This recording is the final video evidence for the corrected public-testnet lifecycle. + +## Honesty note + +The 2026-06-03 public-testnet run (`ProgramId 4153e159…`, `ImageID 59e15341…`) is superseded historical evidence only. It used the pre-fix single-`init` holding pattern; the load-bearing fix evidence is the 2026-06-27 v0.2.0 refreshed run documented above. + +## FURPS Self-Assessment + +### Functionality + +The implementation delivers the requested token mint-authority lifecycle and the reviewer-critical fix. Holding creation is separated from minting, repeated mints accumulate on chain, and revocation is enforced by the authority guard. + +### Usability + +Evaluators can run library tests, inspect the SPEL-generated IDL, try the examples, and run localnet verification from a clean clone. Public-testnet re-query now succeeds on the current reset-era evidence and fails closed if the endpoint resets again. The requested fresh redeploy/re-anchor is complete using the v0.2.0 client/runtime path. The final narrated video is recorded and linked above. + +### Reliability + +The codebase contains deterministic contract tests for variable supply, authority rotation/revocation, repeated minting, and invalid authority paths. The public-testnet verifier checks transaction inclusion, post-revoke non-inclusion, final mint PDA state, and final holding PDA state. It fails closed after reset. The local-sequencer path is also represented in CI and backed by a prepared-host run. + +### Performance + +The submission documents the current LEZ CU visibility limitation clearly. It uses available executor/local sequencer evidence without pretending the public testnet exposes per-transaction CU telemetry. + +### Supportability + +The repository is public, dual-licensed MIT/Apache-2.0, documented, CI-backed, and includes scripts for prerequisite checks, localnet verification, and public-testnet evidence verification. The canonical proof artifacts identify the 2026-06-27 v0.2.0 refreshed public-testnet lifecycle and 2026-06-09 standalone local-sequencer prepared-host run as final evidence. + +## Terms & Conditions + +By submitting this solution, I confirm that I have read and agree to the [Terms & Conditions](../TERMS.md), and that the implementation is original work published under MIT OR Apache-2.0 licensing.