Skip to content

Public beta on the Base Sepolia test network. Payments use test USDC with no real value: do not send real funds. The escrow contract has not had its external security audit yet, and the terms are drafts pending legal review. What the beta means

OpenVPT

01 · Security center

Verify, don't trust: the OpenVPT security center

Your payment sits in a smart contract, not in a OpenVPT account. Here is exactly what we can and cannot do with it, where the keys live, what we store about you and what is still planned.

Status labels

In code: implemented in the OpenVPT codebase today. Design: how production is meant to run; not live yet. Planned: not built yet.

security --summary
custody
non-custodial escrow contract
release rule
2 of 3 signatures
keys held by OpenVPT
1 of 3
withdraw function
does not exist
third-party audit
planned, not done yet

02 · Funds

What we can and cannot do with your funds

Payments go into the VPTEscrow contract. It releases money only when two different parties out of three (buyer, seller, platform) sign the same split. OpenVPT holds one of the three keys.

The contract owner can

Four admin switches. None of them moves money.

  • Pause new funding

    Stops new fund() calls. Orders that are already funded can still be settled while the contract is paused.
  • Rotate the platform signer

    Replaces the platform's key. It is still one key of three: every settlement also needs the buyer or the seller.
  • Edit the token allowlist

    Chooses which tokens new orders may use (USDC in the MVP). Orders that are already funded are not affected.
  • Set the fee recipient

    Chooses the address that receives the platform share of future settlements.

Nobody can, including us

Enforced by the contract code, not by policy.

  • Withdraw escrowed funds

    The contract has no withdraw or sweep function. Money leaves only through settle().
  • Release money with one key

    settle() needs two valid signatures from two different parties. The same key twice is rejected.
  • Pay out more than was funded

    The seller, buyer and platform shares must add up exactly to the funded amount, and each order settles only once.
  • Abandon the contract

    Ownership cannot be renounced. It moves only through a two-step transfer that the new owner has to accept.
VPTEscrow.settle()
signatures
2 distinct of {buyer, seller, platform}
split
toSeller + toBuyer + toPlatform == amount
platform share
toPlatform >= fee * toSeller / amount
replay
settled once, then closed
submitted by
anyone; authority comes from the signatures

Honest limits

  • Settle signatures do not expire and cannot be revoked. That is why the platform signs a settlement at most once per order.
  • If OpenVPT stopped operating, the contract would still accept a settlement signed by the buyer and the seller together. Nobody could release funds alone.
  • The contract enforces a minimum platform share, not a maximum. Before your wallet is asked to sign, the app checks that the split matches the order on screen.

03 · Keys

Three keys, one of them ours: key management

Who holds which key, what it can sign, and whether each part runs in code today or is still design.

  • In code

    Buyer key

    Pays with fund() and signs your approval of a settlement. OpenVPT never sees or stores your private key or seed phrase.
    Held by
    Your wallet
  • In code

    Seller key

    Receives the payout and can co-sign a settlement. Payouts go to the wallet address set on the order.
    Held by
    Your wallet
  • In code

    Platform signer

    Co-signs each CreateOrder, so amount, fee and seller cannot be forged, and co-signs settlement proposals. In local development the key is read from an environment variable.
    Held by
    OpenVPT API
  • Design

    Platform signer in KMS / HSM

    In production the platform key is meant to stay inside a cloud KMS / HSM that signs digests, so the private key is never exported. A KMS signer (AWS KMS, secp256k1) is implemented in the API and tested against a simulated KMS. Running it in production waits for the mainnet deployment.
    Held by
    Production design
  • In code

    Relayer key

    Pays the gas to submit settle() once two signatures exist. It cannot change the split or sign for anyone: the contract checks the signatures, not the sender.
    Held by
    OpenVPT API
  • Planned

    Contract owner

    Holds the four admin switches above and nothing else. The deploy script can hand ownership to a separate address such as a multisig safe; a multisig owner on mainnet is planned.
    Held by
    OpenVPT admin

04 · Contract

Contract facts you can check

Compare these values with what your wallet shows before you sign. The web app refuses to pass a payment or settlement message to your wallet if its chain, contract, order or amounts do not match the order on screen.

eip712.domain
name
"VPTEscrow"
version
"1"
chainId
84532
network
Base Sepolia testnet
verifyingContract
0x0000000000000000000000000000000000000000

Mainnet deployment is pending. This address belongs to the Base Sepolia testnet deployment and is not the production contract.

Typed data you may be asked to sign

CreateOrder(bytes32 orderId,address buyer,address seller,address token,uint256 amount,uint256 fee,uint64 expiresAt)
Signed by the platform; checked by fund() and expires after at most 15 minutes.
Settle(bytes32 orderId,uint256 toSeller,uint256 toBuyer,uint256 toPlatform)
Signed by two of buyer, seller and platform; checked by settle().

orderId = keccak256 of the order's UUID

Built with

Solidity 0.8.24 and OpenZeppelin v5: EIP712, ECDSA, SafeERC20, ReentrancyGuard, Ownable2Step, Pausable.

05 · Account

Account security

Protections on the account side, and what happens when an account is banned.

  • Two-factor sign-in (TOTP)

    Add an authenticator-app code to your sign-in from your account. The secret is encrypted at rest and repeated wrong codes are rate-limited.
  • Passwords

    At least 12 characters, stored only as an Argon2 hash. Sign-in is temporarily blocked after repeated failures.
  • Wallet verification (SIWE)

    Wallets are linked with Sign-In with Ethereum (EIP-4361). Each nonce works once and expires after 10 minutes, so a signature cannot be replayed.
  • Sessions

    Refresh tokens rotate on every use. Realtime connections are dropped when their token expires.
  • Banned accounts

    A ban revokes every session, blocks all signed-in requests and realtime connections at once, and pauses the user's listings. Open orders are not frozen: they continue through the other party, the automatic deadlines and arbitration.

06 · Data

What we store and how

We keep what the service needs to run, and protect the sensitive parts.

data-inventory
Data OpenVPT stores and how it is protected
DataHow it is stored
Contact form IP addressOnly a salted SHA-256 hash. The raw IP is never stored.
License keys delivered to buyersEncrypted with AES-256-GCM and bound to the order.
Delivered filesSHA-256 hash recorded at upload. Downloads use short-lived signed links.
Two-factor secretsEncrypted with AES-256-GCM and bound to the account.
PasswordsArgon2 hash only.
Wallet addressesThe public addresses you verified. Never private keys or seed phrases.
Order chatStored with the order. Messages with contact details or outside payment links carry a warning flag.

Card numbers are never collected: payments are made in USDC from your own wallet.

07 · Anti-scam guide

Anti-scam guide: stay on the platform

Most losses in digital-goods trading happen outside the escrow. Five habits keep you inside it.

  1. Pay only through escrow

    Never send USDC straight to a seller's wallet, and ignore "escrow" links from outside OpenVPT. Only fund() on the OpenVPT contract is protected.

  2. Take contact-info warnings seriously

    Order chat flags e-mail addresses, phone numbers, Telegram, WhatsApp, WeChat and outside payment links. A flagged message is not blocked, but moving off-platform is a common first step of a scam.

  3. Verify addresses

    Before you sign, compare the contract address and chain in your wallet with the contract facts on this page. If they differ, stop.

  4. Never share secrets

    OpenVPT will never ask for your seed phrase, private key, password or two-factor code, in chat, by e-mail or anywhere else.

  5. Inspect before you confirm

    Check the delivery within the inspection window. Confirming releases the payment and a settled order cannot be reopened; if something is wrong, open a dispute instead.

08 · Responsible disclosure

Found a bug? Responsible disclosure

If you think you have found a vulnerability in OpenVPT's contracts, API or apps, please tell us privately first.

report.txt
  1. Use the contact form with the Security topic. Security reports are flagged for the team.
  2. Include the affected component, steps to reproduce and the impact you expect.
  3. Test only with your own accounts on a local or test network. Do not access other people's data or funds, and do not run denial-of-service tests.
  4. Give us reasonable time to fix the issue before publishing anything.

Not in place yet

  • Planned

    Bug bounty programme

    Planned. There is no paid bounty today.
  • Planned

    Third-party audit

    Planned. The escrow contract has not been audited by an outside firm yet; today it is covered by the project's own automated tests.

This page describes how the system is built. It is not legal, financial or investment advice.

09 · Further reading

Further reading