Trade with more than your own stake, under rules a contract enforces.
Imprest is a funded-trading desk for perpetual futures on Perpl (Monad). You put up a small stake, trade it under fixed risk rules, and if you hit the profit target you graduate to a desk several times larger. The extra capital is credit from a liquidity pool: you can trade it through your desk but never withdraw it. Every order is checked by the desk contract before it reaches Perpl, and realized profit above your previous high is paid out by the contract.
Status: Monad testnet only. Test tokens, no real money. Built for Monad Metropolis, Track 1 (Onchain Finance & Trading). No independent security audit. Mainnet is not deployed.
Live app: https://imprest-chi.vercel.app · Proof: /proof · Live checks: /status
Traders who can trade but lack capital usually go through prop-firm evaluations, where the rules are written in a policy document and payouts depend on the firm. Imprest puts the rules and the payout in contracts instead:
- Qualifying is mechanical. The profit target, number of closed trades and time in tier are checked by the desk contract. No reviewer decides.
- The limits are enforced inside every order. Leverage, price band, risk floor and daily loss are checked in the same transaction as the trade. An order that breaks a rule reverts.
- Payout is by contract. Realized profit above the high-water mark is split by fixed shares (80% trader on the funded tier) and paid in the same transaction as the claim.
- Credit cannot leave. Pool credit sits in the desk's own Perpl account. Apart from margin in that account, the desk can only send AUSD to the pool (principal, fees, profit share), the trader (claimed profit or final residual), the protocol treasury, or a keeper (a capped bounty, once).
- Sign in with a passkey (Mera). No seed phrase or browser extension.
- Get test tokens. Testnet MON for gas (Monad faucet) and testnet AUSD (button on the dashboard).
- Open a desk with a stake of at least 100 AUSD. The desk opens its own Perpl account.
- Evaluation. Trade BTC/ETH perps on your stake. Demo cohort target: +2% equity over at least 2 closed trades (standard cohort: +8%, 5 trades, 24 h).
- Graduation. Anyone (usually the keeper) calls
graduate(); the contract re-checks the rules and the pool adds credit: a 100 AUSD stake becomes a 500 AUSD desk. - Funded trading under the same per-order rules plus pool exposure caps. A credit fee accrues only while a position is open, capped at 25% of stake.
- Claim. With all positions closed, claim realized profit above the high-water mark. Fees are netted first; the trader gets 80% of the remainder.
If equity falls below the floor (6% under the tier start) or the daily limit (3%), new risk is
refused and anyone can call enforce() to close the desk. Your stake absorbs losses first.
| Works now | Notes |
|---|---|
| Browse the live BTC/ETH market, risk rules, proof and status | No wallet needed |
| Create a passkey account, get test AUSD, open a desk, trade, close, claim | Needs a little testnet MON for approve, open desk, claim and close. Trades are gasless through the hosted relayer (Railway) |
| Watch risk, positions, history and receipts | Without the indexer (it runs only on the developer's machine), History reads the chain directly and covers only the most recent ~5,000 blocks (about half an hour) |
Not available on the hosted site: the Envio indexer (History reads the chain directly instead) and passkey sign-in inside the native mobile app (it needs a linked domain and a development build). Gasless trading is available: trades are relayed by the hosted relayer, which pays the gas.
- /proof: each claim with its receipt, transaction and explorer link.
- /status: live RPC, Perpl and contract checks, plus protocol status from receipts.
- docs/CLAIM_LEDGER.md: every claim and its evidence label.
- proof/receipts/testnet/: raw receipts, each read back on a second RPC.
- /api/version: the commit the live site was built from.
- Demo video: not recorded yet.
- Reproduce locally:
pnpm proof:local(contract suite on Perpl's own bytecode plus a reference model).
| Result | Label |
|---|---|
| ImprestPool and DeskFactory deployed; runtime bytecode matches the build on two RPCs | TESTNET_VERIFIED |
A 6x order sent straight to the desk reverted LeverageExceeded; a premature graduate() reverted GraduationNotEligible |
TESTNET_VERIFIED |
| Real Perpl trades opened and closed; a flat desk closed with 99.95 AUSD paid by contract | TESTNET_VERIFIED |
| Trader-signed intents submitted by the relayer filled on Perpl: from a script (2026-10-07) and, on 2026-10-13, signed in the live website and relayed by the hosted relayer, which paid the gas (open, then a reduce-only close via the Close button) | TESTNET_VERIFIED |
Desk 0xfc65…FCC6 earned +2% over two closed trades; the keeper called graduate(); the pool funded 400 AUSD |
TESTNET_VERIFIED |
| After graduation, two real attempts to reach profit above the high-water mark lost money; the stake absorbed it and pool credit stayed intact | TESTNET_VERIFIED (receipts 06–13) |
| 128 contract tests as of 2026-10-13 (unit, fuzz, invariant, security, paired-desk, partial fills, reversals) against Perpl's own exchange bytecode; reference model 26/26. The original 2026-10-07 run of 120 is kept as a dated snapshot. | LOCAL_REPRODUCTION |
| Pre-registered replay: in-transaction enforcement vs a 1 s keeper, median gap 0.0 bps (n = 51): null result, headline dropped | SIMULATED |
| Qualifying profit claim, mainnet, real outside traders, independent audit | PENDING |
Full list: docs/CLAIM_LEDGER.md. Current state: docs/BUILD_STATE.md.
Every order runs the full rule set and a post-fill equity re-check inside one transaction.
That needs an onchain order book with a programmable account interface (Perpl's execOrder,
negative-PnL stamp and IOC/FOK order types), and gas cheap enough for a multi-call trade.
Measured on Monad testnet: a guarded relayed trade costs about 0.07 MON at 102 gwei. On another
EVM chain the contracts would compile, but without Perpl the venue layer would have to be rewritten.
trader (passkey, Mera) LPs
│ signs orders │ deposit AUSD
▼ ▼
web app / mobile app ──(optional relayer)──► Desk ◄──── ImprestPool
│ reads chain one per trader credit, exposure caps,
│ │ checks every fees, profit share
│ │ order, then
▼ ▼ re-checks equity
Monad RPC ◄───────────────────────── Perpl exchange (desk owns its own account)
▲ ▲
keeper: enforce / graduate DeskFactory: opens desks per cohort policy
indexer (Envio): display-only history
- Contracts (
contracts/src):DeskFactoryopens aDeskper trader under an immutable cohort policy. TheDeskowns a Perpl account, validates and stamps every order, re-checks equity after the fill in the same transaction, accrues the credit fee, and settles.ImprestPoolholds LP capital, funds graduated desks and enforces exposure caps. - Off-chain: the web app and mobile app read the chain directly. The relayer can only submit what the trader signed (EIP-712). The keeper only calls functions the contract would accept anyway. The indexer is display-only; nothing authorizes money from it.
- Details: docs/ARCHITECTURE.md.
| Layer | Technology |
|---|---|
| Chain and venue | Monad testnet (chain 10143); Perpl perpetuals exchange; Agora testnet AUSD |
| Contracts | Solidity 0.8.28 (via-IR), Foundry 1.5.1, OpenZeppelin Contracts 5.4.0 |
| Shared logic | TypeScript package @imprest/core (ABIs, EIP-712, policy pre-check, accounting, verification) |
| Web | Next.js 16, React 19, Tailwind CSS 4, viem 2, lightweight-charts, lucide-react |
| Accounts | Mera passkeys (WebAuthn PRF → derived EVM key; no seed phrase, nothing stored server-side) |
| Mobile | Expo SDK 57 / React Native, same shared core |
| Services | Node relayer and keeper (viem); Envio HyperIndex 3 indexer |
| Testing | Foundry unit, fuzz and invariant tests on Perpl's bytecode; Vitest; Playwright with axe-core; Python reference model |
| Hosting | Vercel (web) |
| Rule (every order) | Enforced by |
|---|---|
| Allowlisted market (BTC, ETH) | Desk |
| IOC or FOK only (no resting orders exist) | Desk stamp |
| Leverage at most 5x | Desk (Perpl clamps rather than rejects, so this is load-bearing) |
| Limit price within 50 bps of mark, closes included | Desk |
| 50 bps negative-PnL cap, 2-block execution window | Desk stamp, enforced by Perpl |
Valid mark for new risk. Reduce-only orders are exempt from new-risk and fee-cap limits and may close at a stale mark, but a desk below a loss limit at a fresh mark cannot use a normal close: it is closed by enforce() (open to anyone), which depends on venue liquidity. Price band and active status always apply |
Desk |
| Equity above the 6% floor and 3% daily floor before and after the fill | Desk (whole transaction reverts) |
| Gross funded exposure per market and per desk under caps | Pool, same transaction |
| Credit fee only while exposed, capped at 25% of stake | Desk |
| Claims flat-only, realized profit above the HWM, fees netted first | Desk |
| Breach / fee-cap settlement: principal, keeper (once), fees, trader | Desk + Pool |
Known risks: a price gap larger than the stake can cost the pool principal (see the paired-desk results on /proof); Perpl and Agora admins can freeze or force-close; the code has had an internal automated review only (docs/SECURITY_REVIEW.md).
contracts/ Foundry: Desk, DeskFactory, ImprestPool, SettlementMath; tests on Perpl bytecode
packages/core shared TS: config, ABIs, errors, EIP-712, policy pre-check, accounting, verification
web/ Next.js: landing, trading app, risk center, claims, LP console, /proof, /docs, /status
app/ Expo (React Native) mobile client on the same shared core: Home, Trade, Positions, Risk, Claims, History
relayer/ EIP-712 intent relayer (fetch handler + Node adapter)
keeper/ enforce / graduate / checkpoint watcher (simulate-then-send)
indexer/ Envio HyperIndex v3 config, schema, handlers
scripts/ Gate 0, claims, evidence validator, deployment sync, testnet canonical run
proof/ receipts, experiments, reference model, generated claims
config/ networks.json: the only place addresses live
docs/ architecture, security, threat model, runbooks, status
Prerequisites: Git, Node.js 22, pnpm 11.5 (corepack enable picks the pinned version), Foundry 1.5
(foundryup) and Python 3.12. No keys or funds are needed to build, test or browse the testnet app.
git clone https://github.com/TheWeirdDee/imprest.git && cd imprest
pnpm install
cd contracts && forge build && cd ..
pnpm proof:local # contract suite on Perpl bytecode + reference model
NEXT_PUBLIC_IMPREST_ENV=testnet pnpm --filter @imprest/web dev # http://localhost:3000- Install Expo Go from the App Store or Google Play.
- Put the phone on the same Wi-Fi as this computer.
- Run
npm run mobile(first time:cd app && npm install). - Scan the QR code that appears in the terminal (Android: inside Expo Go; iPhone: Camera app).
Expo Go shows every screen and live testnet BTC/ETH prices. Passkey sign-in, and so your desk and trading from the phone, do not work in Expo Go: it needs a domain linked to the app and a development build. What that takes and costs is in docs/MOBILE.md.
Security: an internal automated review is in docs/SECURITY_REVIEW.md. No independent third-party audit has been performed.
Requirements, every test command and the experiments: docs/SETUP.md. Testnet deployment (needs a deployer key funded with testnet MON): docs/TESTNET_DEPLOYMENT.md. Demo path: docs/DEMO_RUNBOOK.md.
Architecture · Security · Security review · Mobile · Testnet · Threat model · Decisions · Known limitations · Evidence standard · Test matrix · Networks · API · Operations · Failure modes · Sponsor findings · Dependency matrix
Mainnet needs real AUSD seed credit (about 300 AUSD per the PRD) and owner authorization; neither has happened. Perpl's testnet margins in Agora testnet AUSD, so the full AUSD flow is provable on testnet. The register of what needs mainnet, why, and what it costs is in docs/KNOWN_LIMITATIONS.md.
Zero fabrication. Every public number is generated from a file in proof/ and carries its
strongest honest label: PENDING, TARGET, SIMULATED, LOCAL_REPRODUCTION, TESTNET_VERIFIED or
MAINNET_VERIFIED. pnpm validate-evidence fails CI on any violation. User actions in the app
show "verified" only after an independent RPC reads back the expected state.
Imprest was written during the Metropolis build window. The repository's first commit is 2026-10-07, and every commit since is public. No pre-existing Imprest code or product was used as a foundation. The only code not written for this project is the third-party software listed below, used unmodified.
| Component | Where | License | Use |
|---|---|---|---|
| Perpl exchange bytecode and ABIs (perpl-sdk 0.2.9, revision rc_v1.1.7-203) | contracts/perpl-artifacts/ |
MIT | Runs the real exchange in local tests; integration ABIs |
| OpenZeppelin Contracts 5.4.0 | contracts/lib/openzeppelin-contracts/ |
MIT | ERC4626 pool shares, EIP-712, SignatureChecker, SafeERC20, ReentrancyGuard, Ownable2Step |
| forge-std | contracts/lib/forge-std/ |
MIT / Apache-2.0 | Test framework |
Mera (@category-labs/mera) |
npm | see package | Passkey (WebAuthn PRF) accounts |
| viem, Next.js, React, Tailwind CSS, lightweight-charts, lucide-react, Expo, Envio, Playwright, axe-core | npm | see each package | Libraries and tooling, unmodified |
Full dependency list: the package.json files and docs/DEPENDENCY_MATRIX.md.
AI tools (Anthropic's Claude) drafted, under review, the contracts, tests, services, web app, scripts, experiments and documentation in this repository. The human author specified the product, the policy rules, the invariants and the economic parameters in the PRD, and is responsible for reviewing them line by line before any capital is involved. All measured results were produced by running the code in this repository; none were written by hand.
MIT
