Skip to content
PredictFlow

Security

Designed to fail closed on every boundary.

PredictFlow is non-custodial — your key never leaves your wallet extension. But non-custodial alone is not safe. A compromised upstream or a malformed quote response could still slip a malicious transaction into your signing prompt. These defenses exist because prediction markets move real money and the threat model deserves it.

The four-gate signing pipeline

Before your wallet opens its signing UI, every transaction passes through these gates in order. Any failure blocks the prompt and surfaces an explicit error.

1

Payload size limit

Any DFlow /order response larger than twice the Solana max transaction size is rejected outright. Protects against a malicious upstream trying to push an oversized binary.

2

Decode with @solana/web3.js

The transaction is parsed into its VersionedTransaction form before any other check runs. Malformed payloads fail here and never reach the signing prompt.

3

Program whitelist assertion

Every instruction target is checked against a strict allowlist: System, SPL Token, Associated Token Account, ComputeBudget, Memo, and the DFlow router program (configured via VITE_DFLOW_ALLOWED_PROGRAMS). Anything else — rejected.

4

RPC preflight simulation

The final gate runs simulateTransaction against your configured Solana RPC (with sigVerify disabled and recent blockhash replaced). A server-side attempt to drain a wallet fails here and never reaches the wallet prompt.

Content-Security-Policy

The application ships a strict CSP that enumerates every origin it's allowed to reach. Any script or fetch to an unlisted host is blocked by the browser, regardless of what the app code tries to do.

default-src 'self';
base-uri 'self';
object-src 'none';
frame-ancestors 'self';
form-action 'self';
img-src 'self' data: https://phantom.app https://solflare.com https://backpack.app;
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
font-src 'self' data: https://fonts.gstatic.com;
script-src 'self';
connect-src 'self'
  https://*.dflow.net
  wss://*.dflow.net
  https://*.solana.com
  https://*.helius-rpc.com
  https://*.quiknode.pro
  https://*.triton.one;
manifest-src 'self';
worker-src 'self' blob:;
upgrade-insecure-requests;

Defense in depth

Wallet isolation

Only browser-injected providers are supported (Phantom, Solflare, Backpack). No WalletConnect bridge, no remote signing — every signature happens in the wallet extension you installed.

Idempotency & locks

Every submit carries an X-Idempotency-Key header. A module-level submission lock prevents double-signing across component remounts or rapid double-clicks.

Privacy

Wallet pubkeys are SHA-256-hashed before any analytics event. Error messages are stripped of HTML and control characters before reaching Sentry.

Safety flags off by default

VITE_ALLOW_SYNTHESIZED_MINTS and VITE_ALLOW_SIMULATED_FILLS default to false in production. Real-money deployments can never accidentally fake a fill.

What PredictFlow doesn't do

Responsible disclosure

Found a vulnerability in the client, the Pages Function proxy, or the deploy tooling? Email [email protected] with reproduction steps. We'll respond within 72 hours.

Security audited? No — but it's open source.

Every line of the transaction pipeline is in the repo. Audit it yourself, or invite the researcher of your choice.