Cross-chain swap security model — non-custodial / zero-approval architecture
Non-custodial + zero approvals + irreversible on-chain settlement = no attack surface for funds
Core principles
UpSwap never holds user assets at any point in time (non-custodial). We are not a custodian, not a clearing house, and not a settlement layer — we are simply a routing layer that finds the best quote for the user.
The security model of a traditional centralized exchange (CEX) is built on "trust the operator" — a hacker breaching the hot wallet means all user assets are lost. UpSwap's security model is the inverse: our servers have no attack surface for funds at all.
Even if UpSwap's servers, domain, and Cloudflare Worker were fully compromised, an attacker could not take a single unit of user funds — because our code paths never touch assets in the first place.
| Dimension | CEX custodial | Traditional DEX swap | UpSwap |
|---|---|---|---|
| Asset custody | Platform hot wallet | User wallet | User wallet |
| Token approval | N/A | Requires infinite approval | No approval needed |
| Server breach | Total loss of funds | Limited impact | Zero loss of funds |
| Phishing vector | Fake login page | Fake approval popup | Only tricking the user into entering a wrong address |
Fund flow
Here is how funds, addresses, and signatures move through a typical cross-chain swap — note where UpSwap appears, and where it does not.
- Step 1 · Quote — the user enters the amount, asset, and receiving address in the widget; UpSwap requests quotes from upstream routing networks (liquidity vendors) and returns an all-in fixed "You receive X" quote. At this point funds have not left the user's wallet — UpSwap is only a query layer in the middle.
- Step 2 · The user initiates a send from their own wallet → a one-time deposit address (generated by the upstream vendor for this specific order). Funds move from the user's wallet directly on-chain to the deposit address — never through any UpSwap server, never through any intermediary account.
- Step 3 · The upstream vendor detects the incoming deposit → executes the cross-chain swap (sell on the source chain / buy on the destination chain, or via atomic swap). The entire process completes on-chain and inside the upstream network — UpSwap signs nothing and matches nothing.
- Step 4 · The output asset is sent by the upstream vendor directly to the receiving address the user provided. The user's wallet receives the asset and the order is complete. In this step UpSwap merely reads the "completed" status from the vendor's status API and updates the widget UI.
In short: UpSwap appears before Step 1 (quote lookup); from then on, every movement of real money happens between "user wallet ↔ chain ↔ upstream routing network" — we hold no private keys, no intermediary accounts, and no approval permissions.
Replay protection
UpSwap issues an HMAC-SHA256-signed quoteId for every quote, ensuring the quote a user receives cannot be tampered with, cannot be consumed twice, and cannot be reverse-engineered to reveal the upstream vendor's identity.
- Minimal payload: the quoteId encodes only two fields,
{nonce, issuedAt}— no price, no routing information, no vendor identifier. Even if a client decodes the quoteId, it cannot tell which upstream vendor handled the order. - HMAC signature: the server signs the payload with HMAC-SHA256 using a secret kept in Worker environment variables; any tampering with the nonce fails signature verification (401).
- Single-use nonce: the nonce is stored short-term in Cloudflare KV with a TTL; on order confirmation we run
KV.delete(nonce), after which the same quoteId can never be used again — eliminating replay attacks. - Validity ≤ 30 seconds: a quoteId whose
issuedAthas expired is rejected outright, even with a valid signature, shrinking the abuse window.
Privacy is security
We believe "not collecting" is the strongest form of data protection — no database means nothing to steal (no DB to dump).
- Zero accounts: no sign-up, no email, no phone number, no password, no KYC documents — we do not know who you are.
- Zero private key contact: no UpSwap code path ever reads, transmits, or stores a user's private key or seed phrase.
- Minimal logging: IP addresses are used for anti-abuse and automatically deleted after 14 days; order metadata (order ID / amount / timestamp) is deleted after 6 months.
- No third-party tracking: no Google Analytics, no Meta Pixel, no ad-attribution scripts of any kind.
A side effect: even if a regulator or law enforcement agency demands "the transaction history of user A", we genuinely have nothing to hand over — not a refusal to cooperate; the data simply does not exist.
Transport and storage
- HTTPS-only: TLS 1.3 enforced site-wide, HSTS
max-age=31536000; includeSubDomains; preload(1 year), submitted to the Chrome HSTS preload list. - HTTP/3 ready: Cloudflare edge nodes enable QUIC + HTTP/3 by default, reducing time to first byte (TTFB).
- Worker secrets: all upstream API keys and the HMAC secret are stored encrypted via
wrangler secret put— no plaintext in code, and no.envin the git repository. - KV replication across PoPs: nonce data is replicated by Cloudflare KV across global edge nodes, spreading the failure domain — sensitive fields are never sent to the client.
- Zero sensitive data on the client: browser localStorage caches UI preferences only (theme / language) — no tokens, no sessions, no PII.
CORS and middleware
The UpSwap widget is designed to be embeddable on third-party websites, so the API must allow CORS. A set of middleware policies keeps "open CORS" from degrading into "open abuse".
- Wildcard CORS + noindex:
/api/*returnsAccess-Control-Allow-Origin: *together withX-Robots-Tag: noindex— cross-origin calls are allowed, but search engines are barred from indexing the endpoints. - Case-folding guard: middleware lowercases the path (
toLowerCase) before routing, blocking bypass attempts like/API/Quote. - CORS headers even on errors: when the backend catches an exception and returns a 5xx, middleware still guarantees the CORS headers are present, so embedding sites can read the error instead of guessing blindly.
- Rate limit: sliding-window limiting by IP + endpoint prevents scripted brute-forcing of nonces.
Third-party dependencies and audits
UpSwap's own codebase contains no proprietary smart contract — we are an Astro + React frontend plus a Cloudflare Worker edge proxy. So a "contract audit" simply does not apply to us. What actually moves funds are the upstream routing networks and cross-chain bridges.
- Every upstream vendor is independently audited: each upstream liquidity vendor we integrate has passed an independent audit by a leading security firm. For commercial confidentiality we do not name specific vendors on public pages; likewise, to avoid misleading users, we do not list the audit firms here — that could be read as "UpSwap itself was audited by these firms". UpSwap has no proprietary smart contract, so there is no UpSwap-side audit to be had.
- npm dependency monitoring: Renovate tracks dependency upgrades automatically, Socket.dev scans for supply chain attacks in real time, and high-severity CVE patches are typically merged within 24 hours.
- Minimal-dependency principle: the widget bundle is < 80 KB compressed, and every npm package has been scrutinized for "is it actually necessary".
Our honest limits
The worst sin of a security document is promising everything. Below are the scenarios UpSwap objectively cannot defend against — written here so you know in advance.
Wrong receiving address entered by the user: on-chain transactions are irreversible. If a character is dropped while copy-pasting, a deprecated old address is used, or the address does not support the destination asset, the funds are irreversibly lost — neither we nor the upstream vendor can recover them. Always double-check the receiving address before confirming.
An upstream vendor gets attacked: each vendor is independently audited, but no code is absolutely secure. If an incident occurs in an upstream routing network, orders that are "sent but not yet received" may be affected. We commit to announcing immediately and assisting with tracing, but we cannot backstop losses with UpSwap's own funds.
Phishing sites impersonating UpSwap: social engineering attacks like this cannot be eradicated by technical means. Verify the address bar reads https://upswap.io every single time, and beware of lookalike domains such as upswap-io.com / 99bio.com / 99b.app. UpSwap will never DM you first, never ask for your private key, and never ask you to "transfer funds to verify your account".
Retransfer gas on failed-order refunds: in rare cases an order cannot complete and triggers an automatic refund to the source address; the gas for that on-chain refund transaction is deducted from the refund amount by the upstream vendor — this is the chain's physical rule, not a fee UpSwap charges.
Vulnerability disclosure
If you discover a security vulnerability in UpSwap, we appreciate your responsible disclosure. Please contact us through the channels below, and do not publish a PoC in public channels.
- Email security@upswap.io with a subject line starting with
[SECURITY] - For highly sensitive content, encrypt with our PGP public key (fingerprint at /security/disclosure)
- We commit to acknowledging receipt within 24 hours, an initial assessment within 72 hours, and a fix or mitigation for critical vulnerabilities within 7 days
- Confirmed valid disclosures earn Hall of Fame recognition and UpSwap swag
Full process, scope, and out-of-scope items: see /security/disclosure.