# quay-vm

`no_std` interpreter for the Quay pricing DSL — the per-Strategy
on-chain bytecode that drives `swap` price computation. Single safe
interpreter, used both on-chain (in `quay-program`'s `swap` ix) and
off-chain (in `quay-sdk`'s `simulate_swap`).

## Design pillars

- **Safe by construction.** Every userspace access bounds-checked at
  runtime. No `unsafe` in dispatch. Slice bounds enforce the memory
  boundary; the dispatcher cannot touch other accounts.
- **No install-time validator.** Bytecode is stored as-is at
  `init_strategy`. Bad bytecode fails at first swap with a
  `RuntimeError`; the host program never crashes.
- **Per-strategy userspace.** One `userspace: &mut [u8]` slice per
  Strategy, sized at `init_strategy` and resizable via `resize_userspace`.
  Curves manage their own layout. Both owner (via `set_userspace`,
  partial-write at an offset) and the running bytecode (via `StoreI64`)
  can mutate it.
- **Bounded compute.** Forward-only jumps + bounded bytecode +
  `MAX_STEPS = 1024` step counter + capped table walks.

## Files

| Path | Purpose |
| --- | --- |
| [`SPEC.md`](./SPEC.md) | VM spec — opcodes, safety contract, error namespace, examples |
| `src/vm.rs` | The interpreter (`evaluate`) |
| `src/opcode.rs` | Opcode set + stack-delta table |
| `src/wire.rs` | Zero-copy unpacker for the `test_evaluate` wire format |
| `src/cu_estimate.rs` | Conservative per-opcode CU walker |
| `src/tests.rs` | Unit tests for dispatch + bounds |
| `tests/proptest_safety.rs` | "evaluate never panics" property (proptest) |
| `fuzz/` | `cargo-fuzz` panic-freedom soak target |

## Build & test

```bash
cargo test -p quay-vm         # ~28 unit + 1 proptest
cargo build -p quay-vm        # native build
```

BPF + on-chain integration tests live in `onchain/tests-litesvm`.

## Dependencies

Only `bytemuck` for zero-copy struct casts in `wire.rs`. Safe to import
into any off-chain code that needs to mirror swap-time pricing.
