Mark-relative OTC orders for tokenized private markets on Solana.
MarkDesk lets a holder create an offer such as “sell Anduril at the latest PreStocks mark minus 3%” instead of posting a fixed price that becomes stale. A taker fills with USDC; the Solana program checks a fresh published mark and settles both legs atomically.
Built for the Solana Stocklana hackathon. This repository is an early technical prototype, not an audited production protocol or an offer of financial products.
Private-market tokens can trade far from their reference mark, while thin liquidity can make AMM execution expensive. Existing dashboards explain the gap. MarkDesk turns the gap into an executable rule:
- A publisher reads the official PreStocks catalog and publishes a timestamped mark.
- A maker escrows a supported PreStocks token and chooses an offset in basis points.
- A taker fills the offer with USDC.
- The program rejects stale marks, calculates the quote in integer arithmetic, and settles atomically.
| Component | Status |
|---|---|
| Live PreStocks catalog and fallback snapshot | Implemented |
| Eight-mint Token-2022 inspector and dated evidence | Implemented |
| Fee-aware, scaled-UI mark-relative quote math | Implemented and tested |
| Publisher normalization and canonical payloads | Implemented and tested |
| Anchor config, mark, create, fill, and cancel instructions | Implemented; create/fill/cancel paths SBF-tested |
| Transfer-fee escrow and withheld-fee harvesting | Implemented and validator-runtime tested |
| Active transfer-hook support | Explicitly rejected on-chain until extra metas are supported |
| Wallet transaction UI | Not implemented yet; web app is a read-only protocol preview |
| Devnet / mainnet deployment | Not deployed |
| Security audit | Not audited |
No screen in the app claims a transaction occurred unless it came from confirmed RPC state.
apps/web/ Next.js market board and offer preview
packages/core/ Shared types, PreStocks normalization, and quote math
services/publisher/ Mark ingestion and canonical snapshot writer
programs/markdesk/ Anchor program
tests/validator/ SBF ProgramTest settlement suite
fixtures/ Labeled fallback data
scripts/ Validation and developer utilities
docs/ Architecture, threat model, and delivery plan
Requires Node.js 20+ and npm 10+.
npm install
npm run check
npm run devOpen http://localhost:3000. The web server attempts to load https://prestocks.com/api/prestocks; if upstream is unavailable it uses a clearly labeled repository snapshot.
Run the mark publisher once:
npm run publisher -- --onceThe unsigned normalized snapshot is written to var/marks.json. Key management and on-chain publication are intentionally not faked in this bootstrap.
Re-run the mainnet Token-2022 compatibility scan:
npm run inspect:mints -- --output research/prestocks-mint-scan.latest.jsonSee the dated compatibility report. Results are point-in-time because issuer authorities can change fee, multiplier, pause, and hook settings.
Install stable Rust and Agave CLI 3.0.7, then run the host suite and the pinned SBF validator suite:
cargo test -p markdesk
cargo build-sbf \
--manifest-path programs/markdesk/Cargo.toml \
--tools-version v1.54 \
--force-tools-install \
-- \
--locked
CARGO_TARGET_DIR="$PWD/target" \
cargo test --manifest-path tests/validator/Cargo.toml --lockedThe deterministic SBF run measures 52,607 CU for create, 44,368 CU for fill, and 33,334 CU for cancel on the extension-heavy fixture. See the dated validation report.
The declared program id is a source placeholder until the first deployment. Run anchor keys sync before deploying and commit the resulting program-id change, never a deployer keypair.
- Only the configured quote mint may settle offers.
- Only the configured publisher may update marks.
- Mark sequences must increase and timestamps must be fresh at fill time.
- Offer price calculations use checked
u128arithmetic and round quote amounts up. - Base-token quotes use the buyer's net receipt after the current epoch fee and active scaled-UI multiplier.
- Signed minimum-receive, maximum-quote, and expected-mark-sequence bounds prevent execution races.
- Transfer-fee vaults harvest withheld tokens to the mint before closure.
- Active transfer hooks are rejected until their extra-account metas can be validated and forwarded.
- Makers alone can cancel their offers.
- Each offer PDA is unique to
(maker, offer_id). - The program never treats the upstream API as cryptographically trustless.
See docs/THREAT_MODEL.md before handling real assets.
MarkDesk targets one narrow job: safe, auditable block execution for PreStocks holders without stale fixed-dollar orders. The PreStocks path must not integrate non-PreStocks pre-IPO assets because that would conflict with the sponsor bounty requirements.
MIT