- Add integration test `token_rotate_authority_then_new_authority_can_mint`:
create with self-authority, rotate to external key, verify new authority
mints as rest account, verify old authority is rejected (RFP-001 end-to-end)
- Fix README error table: 'must sign' -> 'must authorize' (matches mint.rs:36)
- Fix guest doc comments for mint/set_authority to describe the 0-or-1
external authority model correctly
- Fix example scripts: new-fungible-definition-with-authority -> new-fungible-definition,
--initial-supply -> --total-supply (align to token-idl.json and demo-full-flow.sh)
Second review round on PR #125 (LP-0013):
- set_authority now rejects foreign-owned definitions. It takes the
ProgramContext and asserts definition_account.program_owner ==
self_program_id, matching mint and initialize_account. Without this a
foreign-owned account with token-shaped data could have its authority
field rewritten. Added test_set_authority_rejects_foreign_owned_definition.
- demo-full-flow.sh now calls instruction and flag names that exist in
the regenerated token IDL: new-fungible-definition (was the nonexistent
new-fungible-definition-with-authority), --total-supply (was
--initial-supply), and drops --authority-account for the self-authority
mint/set-authority path (the rest account is --authority-accounts and is
empty when the definition is its own authority).
- Stripped a trailing-space lint nit in docs/LP-0013-README.md.
Addresses review on PR #125 (LP-0013):
#1 authority transfer now hands control to the new signer. mint and
set_authority take a trailing authority_accounts (Vec<AccountWithMetadata>):
empty preserves the original self/PDA-authority behavior (AMM unchanged),
one entry lets an external/rotated authority actually mint or rotate again.
Tests: rotated_authority_can_mint, rotated_authority_old_key_cannot_mint.
#2 metadata-backed fungibles take a real mint_authority instead of a
hardcoded Authority::renounced(), matching the plain-fungible supply model.
Test: test_metadata_fungible_with_authority_is_mintable.
#3 demo-full-flow.sh resolves TOKEN_BIN from the README-documented
cargo risczero build output, falling back to the workspace build, with an
explicit TOKEN_BIN override still respected.
Regenerated token-idl.json for the new trailing authority_accounts.
Addresses @0x-r4bbit's review:
- lez-authority now provides an Authority(Option<[u8;32]>) newtype and an
Ownable trait (require_owner / transfer_ownership / renounce_ownership);
programs embed the authority slot in their account type instead of calling
a wrapper. Replaces the old AuthoritySlot.
- TokenDefinition::Fungible embeds authority: Authority; TokenDefinition
implements Ownable.
- Fold mint authority into NewFungibleDefinition { mint_authority: Option<AccountId> };
remove the separate NewFungibleDefinitionWithAuthority instruction.
- mint/set_authority authorize against the definition account itself (its id
must match the stored authority and be authorized in the tx), restoring the
2-account mint shape and supporting PDA authorities.
- Fix AMM: the pool-definition PDA is now the LP token's mint authority, so the
AMM mints LP at creation and on add-liquidity (was permanently revoked).
- Instruction params use AccountId; remove LP-0013-specific comments.
- Regenerate token/amm/ata/stablecoin IDLs.
Tests: lez-authority 8, token unit 56, token/amm/stablecoin/ata integration all
green under RISC0_DEV_MODE=1; fmt + clippy clean.
- set_authority rejects all-zero new_authority on rotation (matches creation guard)
- SetAuthority/Mint doc comments now list the required authority signer account
- README: add --authority-account to mint/set-authority CLI examples,
correct error-code table to actual panic strings, make program ID build-dependent
- 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
Bump the LEZ dependency from the `lez-core-v0.2.0` tag to `v0.2.0-rc6` across
the workspace and all guest manifests (still resolving via the renamed
`lee_core`/`lee` packages), and regenerate the lockfiles to match.
rc6 moved the clock program out of `nssa` into a separate system-programs crate
(gated behind the guest-building `artifacts` feature), so adapt the tests:
- Import `ClockAccountData` and `CLOCK_01_PROGRAM_ACCOUNT_ID` from `clock_core`
instead of `nssa`, and build clock data via `ClockAccountData::to_bytes()`
rather than hand-encoding the Borsh layout.
- `V03State::new()` no longer auto-creates the clock account, so AMM tests seed
the canonical 1-block clock explicitly before ops that read it.
- `advance_clock` now writes the clock account directly via
`force_insert_account` (the clock can no longer be ticked with a real
transaction), matching how upstream rc6 state-machine tests seed accounts.
- Add the `clock_core` dependency to integration_tests/benchmark.
Bump the LEZ dependency from the `v0.2.0-rc3` tags to the released
`lez-core-v0.2.0` tag across the workspace and all guest manifests. The crate
was renamed upstream, so `nssa_core`/`nssa` now resolve via the `lee_core`/`lee`
packages, and spel-framework points at the `refactor/lez-v020-compat` fork
branch for compatibility.
Adapt the integration tests to the new API surface:
- `NssaError` is now `LeeError` (error variants unchanged).
- Account inputs move from numeric mask vectors (`vec![2, 0, 0]`) to typed
`InputAccountIdentity` values (e.g. `PrivateUnauthorized { epk, view_tag,
npk, ssk, identifier }`).
- `ViewingPublicKey::from_scalar` → `from_seed(d, z)`; `AccountId::from(&npk)`
→ `AccountId::for_regular_private_account(&npk, 0)`; ephemeral-key/shared-
secret setup → `SharedSecretKey::encapsulate_deterministic(...)` with the
circuit filling the EPK.
Regenerate all guest Cargo.lock files and the workspace lockfile to match.
Configure guest release profiles with debug = 0 and strip = "symbols" so deployed RISC Zero artifacts use stripped binaries.
Document that release-profile ImageIDs are canonical for testnet and mainnet deployments and dependent values must be refreshed.
Adds the CreatePriceObservations instruction to the TWAP oracle program.
The instruction initialises a PriceObservations PDA for a given price
source account and time window, writing the initial tick and timestamp
as the first entry.
Key design decisions:
- Per-window accounts: each (price_source, window_duration) pair maps to
a distinct PriceObservations PDA. The window duration is baked into the
PDA seed so a single price source can support multiple TWAP windows
(24h, 7d, 30d) at independent sampling rates without sharing a buffer.
- window_duration not stored on struct: it is implicit in the PDA address.
Any reader that located the account already knows the window duration
used to derive it. Storing it would be redundant.
- Authorization is implicit: the PriceObservations PDA is derived from
the price source account ID, so is_authorized = true on the price source
proves the caller controls it without a redundant authority field.
- Impersonation is prevented by the PDA check: passing a controlled price
source with a victim's observations account ID fails immediately because
the computed PDA (from the attacker's source) does not match.
Closes#126