Solution: LP-0013 - Token Program Improvements: Authorities#125
Solution: LP-0013 - Token Program Improvements: Authorities#125bristinWild wants to merge 16 commits into
Conversation
- Add lez-authority crate: agnostic AuthoritySlot library (RFP-001) - Add mint_authority field to TokenDefinition::Fungible - Add NewFungibleDefinitionWithAuthority instruction - Add SetAuthority instruction (rotation + permanent revocation) - Update Mint to enforce authority guard - Wire new instructions into guest binary - Add 8 authority unit tests (53 total passing) - Add LP-0013 README, IDL, demo script, and example scripts
|
Hi @fryorcraken, workflow approval needed for CI to run on this PR when you get a chance. Thanks! |
There was a problem hiding this comment.
Pull request overview
Implements LP-0013 mint-authority support for the token program by extending the fungible token definition with an optional mint_authority, adding creation + authority-management instructions, wiring guest dispatch/IDL, and adding docs/tests/scripts demonstrating the authority lifecycle.
Changes:
- Add
mint_authority: Option<[u8; 32]>toTokenDefinition::Fungible, plusNewFungibleDefinitionWithAuthorityandSetAuthorityinstructions. - Update
mintto reject minting when authority is revoked (mint_authority == None) and add unit/integration tests for the authority lifecycle. - Add the standalone
lez-authoritycrate, regenerate IDL artifacts, and add docs/demo/example scripts for LP-0013.
Reviewed changes
Copilot reviewed 25 out of 26 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| token-authority.idl.json | Adds an additional IDL-like JSON file describing the token program + authority instructions. |
| scripts/examples/variable_supply_token.sh | Example script for authority rotation on a variable-supply token. |
| scripts/examples/fixed_supply_token.sh | Example script for revoking authority to create a fixed-supply token. |
| scripts/demo-full-flow.sh | End-to-end demo script using lgs + spel to exercise the authority lifecycle. |
| programs/token/src/tests.rs | Updates fixtures for new mint_authority field and adds authority unit tests. |
| programs/token/src/set_authority.rs | New handler for rotating/revoking mint authority. |
| programs/token/src/new_definition.rs | Initializes mint_authority for existing creation flows and adds new_fungible_definition_with_authority. |
| programs/token/src/mint.rs | Adds rejection when mint authority is revoked. |
| programs/token/src/lib.rs | Exposes the new set_authority module. |
| programs/token/src/burn.rs | Updates fungible match to include mint_authority. |
| programs/token/methods/guest/src/bin/token.rs | Wires guest entrypoints for new_fungible_definition_with_authority and set_authority. |
| programs/token/core/src/lib.rs | Extends core instruction enum + token definition with mint_authority. |
| programs/stablecoin/src/tests.rs | Updates token definition test fixtures to include mint_authority: None. |
| programs/integration_tests/tests/token.rs | Adds integration tests for “create with authority” and “revoke authority”. |
| programs/integration_tests/tests/stablecoin.rs | Updates token definition fixtures to include mint_authority: None. |
| programs/integration_tests/tests/ata.rs | Updates token definition fixtures to include mint_authority: None. |
| programs/integration_tests/tests/amm.rs | Updates token definition fixtures and a fungible definition matcher to include mint_authority. |
| programs/ata/src/tests.rs | Updates token definition fixtures to include mint_authority: None. |
| programs/amm/src/tests.rs | Updates token definition fixtures to include mint_authority: None. |
| programs/amm/src/new_definition.rs | Updates LP token definition to include mint_authority: None. |
| lez-authority/src/lib.rs | New program-agnostic AuthoritySlot library + unit tests. |
| lez-authority/Cargo.toml | Adds crate manifest for lez-authority. |
| docs/LP-0013-README.md | New design/usage documentation for LP-0013, including CLI + demo instructions. |
| Cargo.toml | Adds lez-authority to the workspace members. |
| Cargo.lock | Locks the new workspace crate dependency graph. |
| artifacts/token-idl.json | Regenerated IDL including the new instruction(s) and mint_authority field. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- mint.rs: validate caller account_id matches stored mint_authority key - set_authority.rs: validate caller matches mint_authority before rotation/revoke - tests.rs: align AUTHORITY constant and fixtures to match account_id [15; 32] - demo-full-flow.sh: fix --public flag, remove || true from spel commands, update test count to 60
- mint.rs: validate caller account_id matches stored mint_authority key - set_authority.rs: validate caller matches mint_authority before rotation/revoke - tests.rs: align AUTHORITY constant and fixtures to account_id [15; 32] - integration_tests/token.rs: derive authority_key from Ids::token_definition() so stored key matches actual signer account ID; update all affected asserts - demo-full-flow.sh: fix --public flag, remove || true from spel commands, update test count to 60 60 unit tests + 16 integration tests passing (RISC0_DEV_MODE=1)
|
Addressed all Copilot review items and integration test gaps: mint.rs: now validates account_id == mint_authority key before allowing mint - previously only checked is_some(), so anyone controlling the definition account could mint regardless of who the stored authority was Medium: Demo script: fixed account new --public flag (was missing --, would produce empty account IDs on a clean machine) Integration tests (same root cause as unit tests): authority_key now derived from Ids::token_definition() (real signer account ID derived from PrivateKey([10; 32])) instead of hardcoded [9; 32] - the old value never matched the actual signer so SetAuthority and Mint would have failed against the live sequencer Style: Replaced .unwrap() with .expect() on try_into() calls per clippy -D unwrap_used Results: 60 unit tests + 16 integration tests passing (RISC0_DEV_MODE=1 and RISC0_DEV_MODE=0), fmt and clippy clean. |
|
I will let Copilot review until it generates no more comments than I will review it |
…s/token-idl.json)
…fied spel flow - replace unverified 'lgs wallet -- token' subcommands with the same spel invocations as demo-full-flow.sh (correct flags, base58->hex authority) - use the new --authority-account signer model - remove misleading || true error-swallowing and false 'verified' claims; point to the unit/integration tests that actually prove the guarantees
- new_fungible_definition_with_authority rejects all-zero mint_authority (RFP-001 reliability) - add test_new_fungible_definition_with_authority_rejects_zero_authority - restore demo-full-flow.sh (had been overwritten with example content); now uses the correct account parsing, base58->hex authority, and --authority-account flag - commit updated Cargo.lock files for the lez-authority dependency
|
Pushed a substantial refactor addressing all Copilot review items (commits 308de62 → 0b8d4c2):
|
| let mut slot = AuthoritySlot(*mint_authority); | ||
| slot.set(signer, new_authority) | ||
| .expect("SetAuthority failed"); | ||
| *mint_authority = slot.0; |
| ### Error Codes | ||
|
|
||
| | Condition | Message | | ||
| |---|---| | ||
| | Mint with revoked authority | Mint authority has been revoked; this token has a fixed supply | | ||
| | SetAuthority without authorization | Definition account authorization is missing | | ||
| | SetAuthority on already-revoked | Mint authority already revoked; supply is permanently fixed | |
| /// Set or rotate the mint authority for a fungible token definition. | ||
| /// Pass `new_authority: None` to permanently revoke minting (fixed supply). | ||
| /// | ||
| /// Required accounts: | ||
| /// - Token Definition account (initialized, authorized by current mint authority). | ||
| SetAuthority { new_authority: Option<[u8; 32]> }, |
| ### Mint tokens | ||
|
|
||
| ```bash | ||
| spel --idl artifacts/token-idl.json --program <token-binary> \ | ||
| -- mint \ | ||
| --definition-account <DEF_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> \ | ||
| --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> \ | ||
| --new-authority none | ||
| ``` |
|
Hey @bristinWild ! Thank you for the PR. |
Implements LP-0013: mint authority model for the LEZ token program.
What's implemented
lez-authority/— standalone agnosticAuthoritySlotlibrary (RFP-001)mint_authority: Option<[u8; 32]>field onTokenDefinition::FungibleNewFungibleDefinitionWithAuthorityinstructionSetAuthorityinstruction — atomic rotation and permanent revocationMintupdated — authority-gated, deterministic rejection when revokedartifacts/token-idl.jsonregenerated viaidl-gendocs/LP-0013-README.md— architecture, CLI usage, CU costs, program IDscripts/demo-full-flow.sh— end-to-end demo with RISC0_DEV_MODE=0scripts/examples/— fixed supply + variable supply examples##Demo video
Link - https://youtu.be/4E7lBgdNwb4
Original submission
logos-co/lambda-prize#56 (as requested by @fryorcraken)