Add the first end-to-end coverage of the oracle's RecordTick path, which previously existed only as native unit tests: - amm_twap_observations_accumulate_across_swaps_and_yield_time_weighted_average: drives swaps + RecordTick across simulated time, then checks the cumulative accumulator and the consulted time-weighted average. - amm_twap_record_tick_sampling_guard_skips_calls_below_min_interval: exercises the min-interval sampling guard through the real instruction path. Running RecordTick through the zkVM surfaced that committing the oracle-owned ~100 KiB observations account costs ~50.9M cycles — over the 2^25 (~33.5M) public-execution limit — so the instruction aborted on chain. Reduce OBSERVATIONS_CAPACITY 6396 -> 2048 (~16.8M cycles, ~half the limit); window coverage is unchanged, only sampling resolution. Add programs/benchmark, a standalone crate (excluded from the workspace so CI and the Makefile skip it) that runs the guest ELF through the RISC Zero executor and reports the per-instruction cycle split, reproducing the on-chain pass/fail at the limit. Its cost-vs-capacity sweep still spans to 6396, guarding against bumping capacity back into the over-budget range.
lez-programs
Essential programs for the Logos Execution Zone (LEZ) — a zkVM-based execution environment built on RISC Zero. Programs run inside the RISC Zero zkVM (riscv32im-risc0-zkvm-elf target) and interact with the LEZ runtime via the nssa_core library.
Programs
| Program | Description |
|---|---|
| token | Fungible and non-fungible token program — create definitions, mint/burn tokens, transfer, initialize accounts, print NFTs |
| amm | Constant-product AMM — add/remove liquidity and swap via chained calls to the token program |
| ata | Associated Token Account program — derives and initializes deterministic token holding accounts for a given owner and token definition |
| stablecoin | Collateral-backed position program — open collateral positions as a foundation for stablecoin debt issuance |
| twap_oracle | TWAP oracle — provides canonical on-chain price accounts consumed by other programs (e.g. stablecoin) |
Apps
| App | Description |
|---|---|
| amm | QML-based UI for interacting with the AMM program |
Running Apps
Apps live under apps/ and are standalone UI applications. Each app has its own README.md with full details.
Apps use Nix flakes. Enable flakes if you haven't already:
mkdir -p ~/.config/nix && echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
Example (apps/amm)
cd apps/amm
# Run the app
nix run .
# Update pinned dependencies
nix flake update
Prerequisites
-
Rust — install via rustup. The pinned toolchain version is set in
rust-toolchain.toml. -
RISC Zero toolchain — required to build guest ZK binaries:
cargo install cargo-risczero cargo risczero install -
SPEL toolchain — provides
spelandwalletCLI tools. Install from logos-co/spel. -
LEZ — provides
walletCLI. Install from logos-blockchain/logos-execution-zone
Build & Test
# Lint the entire workspace (skips expensive guest ZK builds)
make clippy
# Format check
make fmt
# Run unit tests for all programs (no zkVM, no ZK proof generation)
RISC0_DEV_MODE=1 cargo test -p token_program -p amm_program -p ata_program -p stablecoin_program -p twap_oracle_program
# Run integration tests (dev mode skips ZK proof generation)
RISC0_DEV_MODE=1 cargo test -p integration_tests
# Run all tests
make test
Integration tests live in programs/integration_tests/tests/ and cover token, amm, and ata programs end-to-end through the zkVM using RISC0_DEV_MODE=1 to skip proof generation. Each test file corresponds to a program:
programs/integration_tests/tests/token.rsprograms/integration_tests/tests/amm.rsprograms/integration_tests/tests/ata.rs
stablecoin and twap_oracle are tested via their own unit tests (cargo test -p stablecoin_program -p twap_oracle_program).
Compile Guest Binaries
The guest binaries are compiled to the riscv32im-risc0-zkvm-elf target. This requires the RISC Zero toolchain.
cargo risczero build --manifest-path <PROGRAM>/methods/guest/Cargo.toml
Binaries are output to:
<PROGRAM>/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/<PROGRAM>.bin
Deployment
# Deploy a program binary to the sequencer
wallet deploy-program <path-to-binary>
# Example
wallet deploy-program programs/token/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/token.bin
wallet deploy-program programs/amm/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/amm.bin
wallet deploy-program programs/ata/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/ata.bin
wallet deploy-program programs/stablecoin/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/stablecoin.bin
wallet deploy-program programs/twap_oracle/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/twap_oracle.bin
To inspect the ProgramId of a built binary:
spel inspect <path-to-binary>
Interacting with Programs via spel
Generate an IDL
The IDL describes the program's instructions and can be used to interact with a deployed program.
Using the idl-gen crate (no external toolchain required — this is what CI uses):
make idl
Using the spel CLI (requires the SPEL toolchain):
spel generate-idl programs/token/methods/guest/src/bin/token.rs > artifacts/token-idl.json
spel generate-idl programs/amm/methods/guest/src/bin/amm.rs > artifacts/amm-idl.json
spel generate-idl programs/ata/methods/guest/src/bin/ata.rs > artifacts/ata-idl.json
spel generate-idl programs/stablecoin/methods/guest/src/bin/stablecoin.rs > artifacts/stablecoin-idl.json
spel generate-idl programs/twap_oracle/methods/guest/src/bin/twap_oracle.rs > artifacts/twap_oracle-idl.json
Generated IDL files are committed under artifacts/. CI will fail if a program's IDL is missing or out of date.
Invoke Instructions
Use spel --idl <IDL> <INSTRUCTION> [ARGS...] to call a deployed program instruction:
spel --idl artifacts/token-idl.json <instruction> [args...]
spel --idl artifacts/amm-idl.json <instruction> [args...]
spel --idl artifacts/ata-idl.json <instruction> [args...]
spel --idl artifacts/stablecoin-idl.json <instruction> [args...]
spel --idl artifacts/twap_oracle-idl.json <instruction> [args...]