-
Notifications
You must be signed in to change notification settings - Fork 5
Solution: LP-0013 - Token Program Improvements: Authorities #125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
bristinWild
wants to merge
25
commits into
logos-blockchain:main
from
bristinWild:solution/lp-0013-authorities
Closed
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
a8863ab
feat(LP-0013): add mint authority model to token program
cc70332
fix: add mint_authority to amm and fix nightly fmt
0ae30c9
fix: update all programs for mint_authority field, regenerate token IDL
3ba6139
docs: add program ID, CU costs, CLI usage, SDK docs, fix demo script …
cdf6d8f
feat: add E2E integration tests for authority lifecycle
dab552a
fix: make demo script portable with configurable env vars
d15eec7
docs: clean up LP-0013 README with accurate CLI commands and scaffold…
481b34a
fix: correct test count in demo script summary
7e788f4
docs: add RFP-001 compliance section explaining lez-authority alignment
b561f91
fix: enforce mint authority key validation in mint and set_authority
16738c7
fix: enforce mint authority key validation in mint and set_authority
029f617
style: fix rustfmt trailing newline and replace unwrap with expect fo…
175c9d2
refactor: gate mint/set_authority via lez-authority with explicit sig…
ce372c7
chore: remove stale root-level token-authority.idl.json (use artifact…
0cb99fe
refactor(examples): rewrite fixed/variable supply scripts to use veri…
1c41d19
feat: reject all-zero mint authority; restore 7-step demo-full-flow.sh
c2a7d75
fix: address Copilot review round 2
83df203
refactor(authority): embed Authority type in TokenDefinition; fix AMM…
d5837aa
style: cargo fmt after authority redesign
dd8328c
fix: update AMM unit test fixtures for LP token authority
160ff8e
fix(token): support external mint authority; intentional metadata sup…
686a7d0
fix(token): owner-guard set_authority; align demo script to token IDL
aee5372
fix(lp-0013): address review feedback — docs alignment and missing ro…
210e2f4
fix(demo): align spel CLI args to IDL; remove b58_to_hex conversion
b9a4b2d
fix(validator): remove .claude artifacts, add demo.sh and token.idl.j…
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| [workspace] | ||
| members = [ | ||
| "lez-authority", | ||
| "programs/token/core", | ||
| "programs/token", | ||
| "programs/token/methods", | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| token-idl.json |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,218 @@ | ||
| # LP-0013: Token Program Mint Authority | ||
|
|
||
| This document describes the mint authority model added to the LEZ Token program as part of LP-0013. | ||
|
|
||
| ## Overview | ||
|
|
||
| The LEZ Token program now supports a mint authority model for fungible tokens: | ||
|
|
||
| - **Mint authority set at initialization** — create a token with a designated minter | ||
| - **Minting by the authority** — the authority can mint additional tokens at any time | ||
| - **Authority rotation** — transfer minting rights to a new key | ||
| - **Authority revocation** — permanently fix the supply by setting authority to `None` | ||
|
|
||
| The `lez-authority` crate provides a reusable, program-agnostic authority library (RFP-001). | ||
|
|
||
| ## Architecture | ||
|
|
||
| ### Authority Model | ||
|
|
||
| `mint_authority: Option<[u8; 32]>` is added to `TokenDefinition::Fungible`: | ||
| - `Some(key)` — the key holder can mint and rotate/revoke | ||
| - `None` — supply is permanently fixed, minting rejected | ||
|
|
||
| ### New Instructions | ||
|
|
||
| | Instruction | Description | | ||
| |---|---| | ||
| | `NewFungibleDefinitionWithAuthority` | Create token with mint authority | | ||
| | `Mint` (updated) | Now authority-gated — Now authority-gated | | ||
| | `SetAuthority` | Rotate or revoke mint authority | | ||
|
|
||
| ### Atomicity | ||
|
|
||
| `SetAuthority` only mutates state after all checks pass. A failed authorization check returns an error before any write occurs, leaving the prior authority intact. | ||
|
|
||
| ### Error Codes | ||
|
|
||
| | Condition | Message | | ||
| |---|---| | ||
| | Mint when authority revoked | Mint authority check failed: Revoked | | ||
| | Mint by non-authority signer | Mint authority check failed: Unauthorized | | ||
| | Mint/SetAuthority without signed authority | Mint authority must authorize the transaction | | ||
| | SetAuthority on already-revoked | SetAuthority failed: AlreadyRevoked | | ||
| | SetAuthority by wrong signer | SetAuthority failed: Unauthorized | | ||
| | Create/rotate with all-zero authority | Mint authority must be a valid non-zero account ID | | ||
|
|
||
| ## Crate Structure | ||
|
|
||
| - `lez-authority/` — Agnostic AuthoritySlot library (RFP-001) | ||
| - `programs/token/core/` — TokenDefinition with mint_authority field | ||
| - `programs/token/src/mint.rs` — Authority-gated minting | ||
| - `programs/token/src/set_authority.rs` — Rotation and revocation handler | ||
| - `programs/token/src/new_definition.rs` — NewFungibleDefinitionWithAuthority handler | ||
| - `programs/token/methods/guest/src/bin/token.rs` — Guest binary dispatch | ||
|
|
||
| ## Module/SDK | ||
|
|
||
| `token_core` provides the reusable types and instructions for building Logos modules. It is already consumed by `amm`, `ata`, `stablecoin`, and `integration_tests` in this workspace: | ||
|
|
||
| ```toml | ||
| [dependencies] | ||
| token_core = { path = "programs/token/core" } | ||
| ``` | ||
|
|
||
| Key types: | ||
| - `TokenDefinition::Fungible { mint_authority, .. }` — token definition with authority | ||
| - `Instruction::NewFungibleDefinitionWithAuthority` — create with authority | ||
| - `Instruction::SetAuthority` — rotate or revoke | ||
|
|
||
| ## RFP-001 Compliance | ||
|
|
||
| LP-0013 has a formal dependency on [RFP-001](https://github.com/logos-co/rfp/blob/master/RFPs/RFP-001-admin-authority-lib.md) — the standardised admin authority library. The `lez-authority` crate in this submission directly implements the approval pattern defined in RFP-001: | ||
|
|
||
| | RFP-001 Requirement | How `lez-authority` satisfies it | | ||
| |---|---| | ||
| | Self-sufficient, agnostic authority library | `lez-authority` has zero program-specific dependencies — it only uses `borsh` for serialisation | | ||
| | Authority slot abstraction | `AuthoritySlot` struct wraps `Option<[u8; 32]>` with `check`, `set`, and revocation semantics | | ||
| | Approval check | `AuthoritySlot::check(signer)` returns an error if the signer does not match or authority is revoked | | ||
| | Rotation | `AuthoritySlot::set(Some(new_key))` atomically rotates to a new authority | | ||
| | Permanent revocation | `AuthoritySlot::set(None)` permanently fixes the supply — subsequent `set` calls are rejected | | ||
| | Reusable by other programs | Any LEZ program can add `lez-authority` as a workspace dependency and use `AuthoritySlot` directly | | ||
|
|
||
| The `lez-authority` crate was also submitted as part of [RFP-001 PR #212](https://github.com/logos-co/spel/pull/212) (the `spel-admin-authority` library with the `#[require_admin]` macro). The two are complementary: `lez-authority` is the lightweight on-chain primitive; `spel-admin-authority` is the SPEL framework macro layer built on top of the same pattern. | ||
|
|
||
| ## Deployment | ||
|
|
||
| The program ID is the hash of the compiled guest ELF and will change whenever | ||
| the guest is rebuilt. Obtain the current ID after building: | ||
|
|
||
| ```bash | ||
| lgs deploy --program-path target/riscv-guest/token-methods/token-guest/riscv32im-risc0-zkvm-elf/release/token.bin | ||
| ``` | ||
|
|
||
| ### Build the guest binary | ||
|
|
||
| ```bash | ||
| cargo risczero build --manifest-path programs/token/methods/guest/Cargo.toml | ||
| ``` | ||
|
|
||
| ### Deploy to the sequencer | ||
|
|
||
| ```bash | ||
| wallet deploy-program target/riscv-guest/token-methods/token-guest/riscv32im-risc0-zkvm-elf/release/token.bin | ||
| ``` | ||
|
|
||
| ## Running Tests | ||
|
|
||
| ```bash | ||
| # Authority unit tests | ||
| cargo test -p lez-authority --lib | ||
| cargo test -p token_program --lib | ||
|
|
||
| # Authority integration tests (zkVM, dev mode) | ||
| RISC0_DEV_MODE=1 cargo test -p integration_tests --test token -- token_new_fungible_definition_with_authority token_set_authority_revoke | ||
| ``` | ||
|
|
||
| ## CLI Usage (via `spel`) | ||
|
|
||
| ### Create token with mint authority | ||
|
|
||
| ```bash | ||
| spel --idl artifacts/token-idl.json --program <token-binary> \ | ||
| -- new-fungible-definition-with-authority \ | ||
| --definition-target-account <DEF_ID> \ | ||
| --holding-target-account <SUPPLY_ID> \ | ||
| --name "MyToken" \ | ||
| --initial-supply 1000000 \ | ||
| --mint-authority <AUTHORITY_KEY_HEX> | ||
| ``` | ||
|
|
||
| ### Mint tokens | ||
|
|
||
| ```bash | ||
| spel --idl artifacts/token-idl.json --program <token-binary> \ | ||
| -- mint \ | ||
| --definition-account <DEF_ID> \ | ||
| --authority-account <AUTHORITY_ID> \ | ||
| --user-holding-account <HOLDER_ID> \ | ||
| --amount-to-mint 500000 | ||
| ``` | ||
|
|
||
| ### Rotate authority | ||
|
|
||
| ```bash | ||
| spel --idl artifacts/token-idl.json --program <token-binary> \ | ||
| -- set-authority \ | ||
| --definition-account <DEF_ID> \ | ||
| --authority-account <AUTHORITY_ID> \ | ||
| --new-authority <NEW_KEY_HEX> | ||
| ``` | ||
|
|
||
| ### Revoke authority (fix supply permanently) | ||
|
|
||
| ```bash | ||
| spel --idl artifacts/token-idl.json --program <token-binary> \ | ||
| -- set-authority \ | ||
| --definition-account <DEF_ID> \ | ||
| --authority-account <AUTHORITY_ID> \ | ||
| --new-authority none | ||
| ``` | ||
|
bristinWild marked this conversation as resolved.
|
||
|
|
||
| ## Example Scripts | ||
|
|
||
| ```bash | ||
| # Fixed supply token (creates with authority, then revokes) | ||
| bash scripts/examples/fixed_supply_token.sh | ||
|
|
||
| # Variable supply token (creates with authority, mints more, optionally rotates) | ||
| bash scripts/examples/variable_supply_token.sh | ||
| ``` | ||
|
|
||
| ## End-to-End Demo | ||
|
|
||
| The demo script must be run from inside an `lgs` scaffold project directory (where the localnet and wallet live): | ||
|
|
||
| ```bash | ||
| # 1. Set up an lgs scaffold (if you don't have one): | ||
| cargo install logos-scaffold | ||
| lgs new my-scaffold && cd my-scaffold | ||
| lgs setup | ||
| lgs localnet start | ||
| lgs wallet topup | ||
|
|
||
| # 2. Deploy the token program: | ||
| lgs deploy --program-path /path/to/lez-programs/target/riscv-guest/token-methods/token-guest/riscv32im-risc0-zkvm-elf/release/token.bin | ||
|
|
||
| # 3. Run the demo: | ||
| RISC0_DEV_MODE=0 bash /path/to/lez-programs/scripts/demo-full-flow.sh | ||
| ``` | ||
|
|
||
| The script will: | ||
| 1. Verify the localnet is running | ||
| 2. Fund the wallet | ||
| 3. Create 3 token accounts (definition, supply holder, recipient) | ||
| 4. Submit `NewFungibleDefinitionWithAuthority` (creates "DemoCoin" with 1M supply) | ||
| 5. Submit `Mint` (mints 500K to recipient → total supply 1.5M) | ||
| 6. Submit `SetAuthority` with `None` (permanently revokes minting) | ||
| 7. Run unit tests to verify authority logic (64 tests) | ||
|
|
||
| ## Compute Unit (CU) Costs | ||
|
|
||
| Measured on LEZ localnet with `RISC0_DEV_MODE=1` (execution only, no proof): | ||
|
|
||
| | Operation | Execution Time | Notes | | ||
| |---|---|---| | ||
| | `NewFungibleDefinitionWithAuthority` | ~11ms | Creates token with mint authority | | ||
| | `Mint` (with authority) | ~10ms | Authority-gated mint | | ||
| | `SetAuthority` (rotate) | ~8ms | Rotates to new key | | ||
| | `SetAuthority` (revoke) | ~8ms | Permanently revokes, sets None | | ||
|
|
||
| Note: With `RISC0_DEV_MODE=0`, full ZK proof generation takes 3–10 minutes per transaction on Apple M-series hardware. LEZ's per-transaction compute budget may change during testnet. | ||
|
|
||
| ## References | ||
|
|
||
| - [lez-authority crate](../lez-authority/src/lib.rs) | ||
| - [SetAuthority handler](../programs/token/src/set_authority.rs) | ||
| - [Mint handler](../programs/token/src/mint.rs) | ||
| - [Solana SPL Token - Set Authority](https://solana.com/docs/tokens/basics/set-authority) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| [package] | ||
| name = "lez-authority" | ||
| version = "0.1.0" | ||
| edition = "2024" | ||
| license = "MIT OR Apache-2.0" | ||
|
|
||
| [lints] | ||
| workspace = true | ||
|
|
||
| [dependencies] | ||
| borsh = { workspace = true } | ||
| serde = { workspace = true, features = ["derive"] } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.