Oracle3
Oracle3: 예측시장 거래 엔진·MCP 서버
자신만의 오프체인 엔진으로 가격을 매긴 개인 금고, 로컬 밸리데이터로 측정, 한도는 페이지에 명시
A private vault with your own capital, priced by your own off-chain engine. Measured on a local validator; the limits are on the page.
금융Rust · TypeScriptGitHub @PropAMMForge온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Builder and SDK for a private proprietary AMM on Solana: one shared program, your own vault, quotes from an off-chain signer, swaps at the posted price. Devnet/localnet only.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Build and run your own proprietary AMM on Solana — a private vault holding your
own capital, priced by your own off-chain engine, quotable by aggregators.
Proprietary market makers take the majority of Solana DEX aggregator volume, but
none of them publish an IDL or an SDK. Every new desk has rebuilt the program,
the pricing engine and the aggregator integration from scratch. This is that
work, packaged: a deployable vault program, a quoting SDK, a CLI that gets you
on chain in five commands, and — as the remaining milestones land — a pricing
engine, a router adapter and a monitoring console.README 전문 보기 ↗Build and run your own proprietary AMM on Solana — a private vault holding your own capital, priced by your own off-chain engine, quotable by aggregators.
Proprietary market makers take the majority of Solana DEX aggregator volume, but none of them publish an IDL or an SDK. Every new desk has rebuilt the program, the pricing engine and the aggregator integration from scratch. This is that work, packaged: a deployable vault program, a quoting SDK, a CLI that gets you on chain in five commands, and — as the remaining milestones land — a pricing engine, a router adapter and a monitoring console.
Status: milestone M1 — the on-chain core. A vault deploys, takes capital from its owner only, quotes parametrically and executes swaps against that quote. Everything past that is listed under Not here yet.
Requires the Solana CLI (Agave 3.1.10) and a keypair with devnet SOL.
forge init . --pair <BASE_MINT>/<QUOTE_MINT> --cluster devnet
forge deploy # create the vault on chain
forge fund --side base --amount 100 # one call per side of the pair
forge fund --side quote --amount 15000
forge quote --mid 150 --spread-bps 10 --size 10
forge status # addresses, balances, quote age
forge init writes a project README of its own describing exactly what was
created and what the next command does.
Swapping is not a forge command by design: the counterparty is a third party,
not the desk that owns the capital. Build the swap instruction with the TypeScript
SDK in packages/sdk, or let an aggregator build it.
One program, many vaults. The bytecode on chain is shared. "Your own AMM" is your own vault — a PDA derived from your owner address and the asset pair — not your own copy of the program. You do not build, deploy or pay rent for bytecode; that is what makes a five-command path possible at all.
Capital belongs to the owner alone. No outside deposits, no LP shares, no claim on profit by anyone else. Deposits from other accounts are rejected by the program, not by convention.
No curve, and no oracle read on chain. Price is not discovered by x*y=k.
The vault stores a mid, a half-spread, an inventory skew and a maximum order
size; the swap computes the output from those. The program never reads a price
feed — an off-chain signer posts the quote. That is the whole reason a swap fits
in a router's compute budget.
Quotes expire in slots. Every quote carries the slot it was posted in, and the program refuses any swap against a quote older than the vault's freshness limit. Posting by hand is for testing; keeping a quote alive is the engine's job.
One pair per vault. A second pair is a second vault with its own capital and its own risk limits. The pair direction is part of the vault address, so the same two mints the other way round is a different vault.
Assets whose transfers change the amount are refused at deploy time. A mint carrying a transfer hook, a transfer fee, a permanent delegate, a pausable or non-transferable extension, or a default-frozen state is rejected when the vault is created — with a message naming the extension — rather than silently making quoted and executed amounts disagree.
Numbers below come from the test suite and the benchmark, not from estimates.
Each is a success criterion in docs/SPEC.md.
| Budget | Measured | |
|---|---|---|
| Empty directory to first swap | ≤ 15 min, ≤ 5 commands | 5 commands, 2.43 s |
| Swap instruction cost | ≤ 60,000 CU | 22,950 CU worst pair, 18,647 CU plain SPL |
| Swaps against a stale quote | 0 of 1,000 (≥ 200 deliberately stale) | 0 of 1,000 |
| Inventory past its hard bound | 0 of 10,000 | 0 over 695 swaps so far |
| Quote on chain after a price move past 5 bps (local network, p95) | ≤ 2 slots | 1 slot, both models, 200 moves, none missed |
| A second pricing model swapped in without touching transport, signing or program | shown by a run | same binary, MODEL_COMMAND only: 100/100 quotes carry each model's fingerprint |
update_quote costs 6,028 CU and deliberately has no declared ceiling: no budget
for it is claimed anywhere, and inventing one would be a number off a shelf.
| Path | What lives there |
|---|---|
programs/propamm-vault | the Anchor program: vault state, quoting, swap, guards |
crates/propamm-quote | the quote math, shared by the program and every consumer |
crates/propamm-cli | forge — init, deploy, fund, quote, status |
crates/propamm-client | the node client, instruction builders and account decoders forge and the engine share |
crates/propamm-engine | the pricing engine: feed, model, update rule, sender, tick loop |
packages/sdk | TypeScript SDK: vendored IDL, instruction builders, event decoding |
apps/web | screen prototype of the console and the deployment wizard |
apps/landing | the project's landing page: static HTML and CSS, no build |
tests/program | instruction-level tests on Mollusk, plus the CU budget gate |
tests/e2e | end-to-end runs against a local validator: the US1 cycle and the engine |
examples/models | pricing models in Python over the engine's model protocol |
apps/web runs on mock data. Every figure on those screens is drawn, not
observed: there is no collector, no database and no chain behind them yet.
Both are published to GitHub Pages by .github/workflows/pages.yml on every
push to main that touches them (Settings → Pages → Source must be set to
"GitHub Actions" once): the landing page at /<repo>/, the prototype under
/<repo>/app/. The Vite base path comes from BASE_PATH and the router takes
its basename from import.meta.env.BASE_URL; to reproduce the build locally:
BASE_PATH=/PropAMM-Forge/app/ pnpm --filter @propamm/web build
The landing page's replay is a recorded engine run, not a drawing:
scripts/wsl-build.sh e2e-engine <file> writes the run's timeline as JSON.
The program must be built with cargo-build-sbf, not anchor build. On this
toolchain anchor build emits SBPFv3, which Agave 3.1.10 will not load — it is
kept only to regenerate the IDL. scripts/wsl-build.sh wraps both, along with
the test, benchmark and end-to-end targets.
scripts/wsl-build.sh build-sbf # the artifact that goes on chain
scripts/wsl-build.sh test # 396 tests
scripts/wsl-build.sh bench-cu # compute-unit report with deltas
pnpm gate # IDL check, lint, typecheck, SDK tests
Program ID: 77Y9n3vWE2noN1u9PTshuWxdDRsrw9UMtejBypUD9wjq.
propamm-engine keeps the quote alive: it reads Pyth Hermes, prices with a
model, and posts with the pricing_authority key when a side moves past the
threshold or the heartbeat is due. Its configuration is the environment; the
keys and their defaults are in .env.example.
cargo build --release -p propamm-engine
target/release/propamm-engine --env-file .env
Four keys are required: SOLANA_RPC_URL, VAULT_ADDRESS (printed by
forge deploy), PRICING_AUTHORITY_KEYPAIR and PYTH_PRICE_FEED_ID; Hermes
also wants PYTH_API_KEY. The engine refuses to start if its key is not the
vault's pricing authority, or if the heartbeat, the model budget or the silence
bound do not fit inside the vault's freshness limit as read from chain.
The pricing model is the one replaceable part. Leave MODEL_COMMAND empty for
the built-in spread-and-skew model, or point it at your own process speaking
the line protocol described in crates/propamm-engine/src/model/external.rs;
examples/models/spread_skew.py is the built-in model ported to Python and
the place to start. The measurement above runs both kinds through the same
binary: scripts/wsl-build.sh e2e-engine.
Named plainly, because a demo without this list creates a false impression of what has been proven:
apps/web are mocks until then.Apache License 2.0 — see LICENSE.