Zap Pilot

Verifiable Strategy — Research Slice

Recompute a single DMA exit using public Vyper bytecode on Arbitrum Sepolia.

Status

Research

The On-chain Calculator demonstrates version 1's exit rule, cross_down_exit, plus its per-asset DMA state machine. It is a research slice, not the production strategy. The contract keeps one exit cooldown for the whole rule, as version 1 did; since version 2 the reference keeps one per asset, and no slice of that is deployed. It does not execute trades or require a wallet.

Current availability

The calculator is available as a research tool. The contract is deployed on Arbitrum Sepolia and Sourcify-verified; the identity card shows its address, deployment transaction, block and pinned codehash. On load, the page fetches the deployed bytecode at a fixed block and checks it against the pinned codehash, reporting "Codehash matches at block …" before any call. Edit the 2025-10-18 real example or try the three what-if scenarios; the crossing tracks visualize your inputs without deciding crosses. Call contract sends the supplied inputs to the deployed contract as read-only eth_calls — warmup → observe → cross_down_exit — at one block. The recorded Python backtest event is labeled separately from the contract answer.

This remains a research slice covering version 1's exit rule, not the production strategy. A contract answer proves what this bytecode returns for the supplied inputs; it does not verify the market data, prior state or production execution. The unedited 2025-10-18 example matches the recorded Python backtest; this does not establish full Python/EVM parity.

Verification method

  1. Check the chain ID is Arbitrum Sepolia (421614). Fetch eth_getCode at a fixed block and compare its keccak256 hash against the compiled artifact.
  2. Call warmup with the previous day's SPY/BTC/ETH prices and DMA values. This derives zones rather than trusting a backend-provided cross flag.
  3. Call observe with that state and the decision day's observations. An example whose original state cannot be reconstructed from warmup must publish explicit state. The page clearly says when that state is used instead.
  4. Call cross_down_exit with the observed views, pre-decision allocation and last execution day. Review the trigger, exit and liquidated masks, cooldown and resulting allocation.
  5. For an unedited example, compare the exact WAD result with the exported pyrevm result. Export also checks the Python winner and target (absolute per-cell tolerance 1e-12), and the published allocation to its four-decimal rounding precision (0.00005).

All three calls and the bytecode check use the same block number. RPC failures, a wrong network, absent code or a mismatched codehash prevent a result. Editing inputs dims the previous answer, labels it stale, and removes the historical-match claim until another call.

Inputs are decimal strings parsed directly with parseUnits(value, 18); excess decimal places are rejected instead of silently rounded in the browser. Allocation totals must equal 100% within a 1e-12 share tolerance to accommodate the original Python weights’ round-trip rounding. This avoids JavaScript float conversion. It does not establish general Python-float parity: the original spike's epsilon and near-DMA counterexamples remain unresolved. The exporter identifies that the engine's original data is float and records its round-trip decimal encoding.

What this proves

Given the displayed inputs, this bytecode produces the displayed output. You can independently inspect its source, deployment, codehash and each call.

It does not prove market prices or DMA are correct, authenticate backend prior state, prove the completeness of the other four rules, or prove production executed a trade. The published decision is a backtest event. An allocation match is not proof of live funds or returns.

Reproduce with cast or curl

After a successful run, expand Verify it yourself. The page generates complete commands for all three calls, including their actual calldata and the fixed block. For example, replace these placeholders with the values shown there:

cast call "$CONTRACT_ADDRESS" --data "$CALLDATA" \
  --block "$BLOCK_NUMBER" \
  --rpc-url https://sepolia-rollup.arbitrum.io/rpc

curl -s https://sepolia-rollup.arbitrum.io/rpc \
  -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"<contract address>","data":"<encoded calldata>"},"<hex block number>"]}'

The copied calldata already includes preceding call results. The expanded inputs/outputs let you verify those connections independently. eth_call is read-only; no signing key or gas payment is needed.

Rebuild the codehash

Use the pinned GitHub source link in the identity card and its repository revision:

cd apps/analytics-engine
uv sync --locked
uv run python scripts/pinned_strategy/compile.py --check

This recompiles using Vyper 0.4.3, Shanghai and gas optimization, then checks the ABI, initcode, runtime bytecode, source hash and runtime keccak256 against the committed artifact. Hash runtime bytecode, not initcode. The page independently hashes eth_getCode from the deployed address.

Operator workflow

Stay on the branch containing the spike artifact. No production strategy or marketing snapshot regeneration is needed.

cd apps/analytics-engine
# Dry run: predicts the CREATE2 address without sending anything.
uv run python scripts/pinned_strategy/deploy.py
# Operator terminal only: hidden getpass prompt, then explicit DEPLOY confirmation.
uv run python scripts/pinned_strategy/deploy.py --broadcast
# If verification was interrupted, resume without signing again:
uv run python scripts/pinned_strategy/deploy.py --transaction <deployment-tx-hash>

The script verifies the deterministic deployer's code, limits chain ID to Arbitrum Sepolia, verifies deployed runtime code, saves deployments.json, and submits source/settings to Sourcify. A pending Sourcify result is recorded honestly and can be resumed. Fund the operator account with Arbitrum Sepolia test ETH; never put a private key in environment variables, shell arguments or chat.

After explicit approval to use production read-only secrets:

infisical run --env=prod -- env DATABASE_READ_ONLY=true \
  uv run python scripts/pinned_strategy/export_landing_examples.py --dates 2025-10-18
uv run pytest tests/scripts/pinned_strategy -q

The exporter can publish verified historical inputs before deployment. It records the actual published 500-day window if no recording exists, rejects a mismatched window, replays the Python strategy with EVM shadow checks, verifies the decision against the committed track record, then writes and formats only its dedicated landing JSON. No private keys or database URLs are included. The existing epsilon parity test remains red until the numerical semantics are explicitly decided; it is not disabled for the demo.

The home page replay itself comes from apps/analytics-engine/scripts/landing/story_replay.py, run against the story bundle that an operator records with:

node scripts/env/run.mjs --environment prod -- pnpm --filter @zapengine/analytics-engine strategy-lab bundle record --name story --start 2025-05-29 --end 2026-10-10

To validate an approved recording before deployment without changing the public JSON, run uv run python scripts/pinned_strategy/export_landing_examples.py --validate-only --dates 2025-10-18. This checks historical Python/pyrevm parity; it does not verify a live deployment. Recorded-history tests also retain the strict DMA-distance relative-error gate, which can fail on the documented Python float versus integer-WAD difference.

After deployment, preserve the frozen examples and update only deployment metadata:

uv run python scripts/pinned_strategy/export_landing_examples.py --refresh-deployment

This does not replay history or read the rolling track record. Rebuild the landing page after updating the bundle. Publication with --dates still requires a matching recorded window and checks the published event and four-decimal allocation. Tests compare recorded replay fields exactly against the frozen example, independently of daily track-record refreshes. --empty explicitly clears examples and is not needed for the normal deployment workflow.

References: deterministic CREATE2 proxy, Sourcify verification, Arbitrum network information.