Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Contributing to Perplex

Thanks for your interest in Perplex. This guide covers the development loop, the standards every change is held to, and how to get a pull request merged.

## Ground rules

- Every change lands via pull request. Nobody pushes to `main` directly.
- All CI checks must be green before a PR is reviewed.
- Branches are preserved on merge — do not use `--delete-branch`.
- Keep PRs focused: one logical change per PR. Large, unrelated diffs are hard to review and slow to merge.

## Prerequisites

- **Rust** (stable, 2021 edition — see `rust-toolchain` / `Cargo.toml` for the pinned version)
- **Foundry** (`forge`, `cast`, `anvil`)
- **Node.js 22+** and **pnpm** (for the web app and SDK)
- **Docker** + **Docker Compose** (local Anvil, Postgres, Redis)

## Local setup

Bring up the full local stack — Anvil, Postgres, Redis, deployed contracts, seeded markets and balances:

```bash
make dev-up
```

For the one-command path that also launches the edge, counterparty bot, and frontend in separate terminals:

```bash
./scripts/dev-up-all.sh
```

Tear down when finished:

```bash
make dev-down # stop containers, keep volumes
make dev-reset # wipe volumes and re-bootstrap
```

## Branching

Branch off `main` using a type prefix:

- `feat/<name>` — a new capability
- `fix/<name>` — a bug fix
- `docs/<name>` — documentation only
- `chore/<name>` — tooling, deps, housekeeping

## Commits

- Verb-first, imperative subject line (e.g. `feat(edge): enforce margin gate on order entry`).
- Keep the subject under ~70 characters; put the *why* in the body when it isn't obvious.
- Group related work into coherent commits rather than one catch-all commit.

## Before you open a PR

Run the same checks CI runs, locally, and make sure they pass:

```bash
# Rust
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace

# Solidity
cd contracts && forge fmt --check && forge test -vvv

# Web (from web/)
pnpm install --frozen-lockfile
pnpm web:typecheck && pnpm web:lint && pnpm web:build
```

End-to-end smoke checks against the local stack:

```bash
make dev-deposit # deposit / withdraw / blocked-withdraw path
make dev-trade # place + match + settle
make dev-liquidate # crash price, verify the liquidation cascade
make sim-replay # replay a market tape against the counterparty bot
```

## Pull requests

- Target `main`.
- Write a clear description: what changed, why, and how it was tested.
- Link any related issue (`Closes #123`).
- Ensure CI is green. A red PR will not be reviewed until it is fixed.
- Address review feedback by pushing follow-up commits to the same branch.

A maintainer merges once the PR is approved and CI is green. Branches are kept after merge.

## Code standards

- **Rust** — idiomatic, `clippy`-clean with warnings denied, `rustfmt`-formatted. Prefer clear names and small functions; match the style of the surrounding module.
- **Solidity** — `forge fmt`-formatted; every money-touching change needs a test, and where applicable a differential or invariant test.
- **Tests** — new behaviour ships with tests. Don't reduce coverage of the matching, margin, settlement, or liquidation paths.
- **Numbers** — money and prices cross the wire as decimal strings, never floats. Follow the existing scaling conventions (`x18`, USDC 6-decimal raw).

## Reporting bugs

Open an issue with: what you expected, what happened, and the minimal steps to reproduce (including the command and environment). For anything that could affect funds or security, please flag it clearly in the issue title.

## License

By contributing, you agree that your contributions are licensed under the repository's [BUSL-1.1](LICENSE) license.
51 changes: 7 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,12 @@ A snapshot of what the platform does today versus what stands between it and a l

| Capability | Why not yet | What it needs |
|---|---|---|
| **Run on a public blockchain** | Runs on a local dev chain (Anvil), not a public network. | Deploy contracts to Arbitrum Sepolia. Currently blocked only on obtaining testnet gas tokens from a faucet — minor. |
| **Handle real money** | Uses test USDC; no real deposits or withdrawals. | A security audit and legal clearance first, then point the vault at real USDC on mainnet. The audit and legal work are the real gatekeepers. |
| **Be reachable on the internet** | Runs only on a local machine; nothing is hosted. | Paid always-on hosting for the backend + database (see below). |
| **Pass a security audit** | No external audit; some hardening still pending (per-order EIP-712 verification, oracle-manipulation guards). | Engage an audit firm — costs money and takes weeks; required before real funds. |
| **Deep, real liquidity** | Only the in-house bot quotes the book. | Recruit external market makers + an incentive program. The fee/rebate rails are already built; this is a business effort, not code. |
| **Operate legally** | Perpetuals are heavily regulated; no entity, geofencing, or terms in place. | A legal entity in a crypto-friendly jurisdiction, region restrictions, and terms of service. Legal, not code. |
| **Run 24/7 reliably** | No always-on host, alerting, or backups. | Hosting + monitoring + database backups. Structured logs and Prometheus metrics are already wired; they just need a host to run on. |

### Hosting — why the live deployment costs money

The engineering is done; making it publicly reachable and always-on is a hosting cost, not a code task.

- **Free tiers don't fit a live exchange.** **Render**'s free tier sleeps after ~15 minutes of inactivity — the whole stack stops until the next request wakes it (slow cold starts, dropped live connections). **Fly.io**'s free allowance is too small to keep the backend + database + keeper always-on. **Vercel** (free) hosts only the frontend, so the site loads but shows no data.
- **Paid, always-on options.** **Railway** (usage-based, ~$5-20/month at this size) runs the backend + Postgres + keeper together and stays awake — best value for a live demo. **Fly.io** (paid, pay-as-you-go) is similarly priced and scales well later.

For a genuinely always-on, shareable URL, expect a modest monthly hosting spend on Railway or Fly.io. Free tiers only suit short, on-demand demos.
| **Run on a public blockchain** | Runs on a local development chain, not a public network. | Mainnet deployment and testing remains. |
| **Handle real money** | Uses test USDC; no real deposits or withdrawals. | A proper security audit first, then point the vault at real USDC on mainnet. |
| **Be reachable on the internet** | Not yet live or hosted. | The application has not yet been deployed to a public host. |
| **Pass a security audit** | No external audit has been done. | A proper security audit is required before handling real funds. |
| **Deep, real liquidity** | Only the in-house bot quotes the book. | External market makers + an incentive program. The fee/rebate rails are already built; this is a business effort, not code. |
| **Operate legally** | Perpetuals are heavily regulated; no entity, geofencing, or terms in place. | A legal entity in a crypto-friendly jurisdiction, region restrictions, and terms of service. |

---

Expand All @@ -90,7 +80,7 @@ For a genuinely always-on, shareable URL, expect a modest monthly hosting spend
| Infra | Docker Compose · Anvil · Postgres 16 · Redis 7 · Prometheus · Grafana |
| Auth | SIWE (EIP-4361) · JWT (HS256) · EIP-712 typed-data order signing |
| Oracles | Pyth Hermes off-chain stream (every environment, ~500ms) · Pyth pull-feed + Chainlink sanity bound on-chain (testnet/mainnet) · `MockOracle` available for deterministic tests |
| Target chain | Arbitrum One (mainnet) · Arbitrum Sepolia (testnet) · Anvil `chainId 31337` (local) |
| Target chain | Arbitrum One (mainnet) |

---

Expand Down Expand Up @@ -353,33 +343,6 @@ Makefile Top-level commands

---

## Component status

| Component | Phase | Status |
|---|---|---|
| `CollateralVault` | 1 | shipped |
| `MarketRegistry` | 1 | shipped |
| `PositionRegistry` (VWAP + health + funding stamp) | 2 | shipped |
| `SettlementEngine` (EIP-712 batched) | 2 | shipped |
| Orderbook + per-market workers | 3 | shipped |
| Differential + invariant tests | 3 | shipped |
| `OracleAdapter` (Pyth + Chainlink sanity) | 4 | shipped |
| `FundingEngine` + Rust SETNX cron | 4 | shipped |
| `LiquidationEngine` + `InsuranceFund` | 4 | shipped |
| ADL socialisation | 4 | shipped |
| REST API (11 endpoints + OpenAPI) | 5 | shipped |
| WebSocket (5 channels, backpressure) | 5 | shipped |
| Counterparty bot (quote agent + kill switch) | 5 | shipped |
| SessionKey contract | 5 | shipped |
| Frontend (Next.js trading UI) | 6 | shipped |
| Redis token-bucket rate limiting | 6 | shipped |
| TypeScript SDK + load test | 7 | pending |
| MegaVault LP backstop | 7 | pending |
| Arbitrum Sepolia bringup | 8 | pending |
| External audit + mainnet rollout | 9 | pending |

---

## Testing

```bash
Expand Down
Loading