r4bbit 51887aa3fb feat(twap-oracle): implement PublishPrice with real tick-to-price conversion
Add PublishPrice — a permissionless instruction that computes the TWAP over a
PriceObservations buffer and writes it to the consumer-facing OraclePriceAccount.

Because each observations account is calibrated to a specific window_duration via
its sampling guard, the oldest valid entry is always the natural window start, so
the TWAP is computed over the full buffer span with no boundary search:

    t2        = most recent observation (write_index - 1, wrapping)
    t1        = oldest valid entry (0 if not full, write_index if full)
    twap_tick = (t2.tick_cumulative - t1.tick_cumulative) / (t2.ts - t1.ts)

If fewer than two observations exist the call is a silent no-op, leaving the price
account at timestamp = 0 (the uninitialized signal consumers already reject). While
the buffer is young the TWAP is computed over the available span, which may be
shorter than the requested window.

The TWAP tick is converted to an actual price ratio via the Uniswap v3 sqrtPriceX96
representation (pure integer, zkVM-safe): get_sqrt_ratio_at_tick(tick) then
sqrtPriceX96^2 / 2^128, yielding a Q64.64 fixed-point ratio stored in
OraclePriceAccount.price. The OraclePriceAccount stays source-agnostic — no tick or
Uniswap framing leaks into the standard. Out-of-range ticks clamp; ratios above 2^64
saturate at u128::MAX. Adds PRICE_FRACTIONAL_BITS = 64; removes the placeholder
TWAP_PRICE_BIAS / oracle_price_to_tick bias encoding.

Pulls in uniswap_v3_math 0.6.2 and alloy-primitives for the conversion. Pins ruint
to =1.17.0 (transitive via alloy-primitives): 1.18 raised its MSRV to rustc 1.90 but
the risc0 guest toolchain ships 1.88. Guest build verified for riscv32im.

Closes #117
2026-06-02 19:52:48 +02:00
2026-03-17 10:18:51 +01:00

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 spel and wallet CLI tools. Install from logos-co/spel.

  • LEZ — provides wallet CLI. 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.rs
  • programs/integration_tests/tests/amm.rs
  • programs/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...]
S
Description
Essential programs for the Logos Execution Zone built by Logos.
Readme MIT
6.6 MiB
Languages
Rust 54.5%
QML 27.8%
C++ 10.2%
JavaScript 4.2%
Shell 1.3%
Other 1.9%