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.
- 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.
- 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.
- 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 | How it is stored |
|---|---|
| Contact form IP address | Only a salted SHA-256 hash. The raw IP is never stored. |
| License keys delivered to buyers | Encrypted with AES-256-GCM and bound to the order. |
| Delivered files | SHA-256 hash recorded at upload. Downloads use short-lived signed links. |
| Two-factor secrets | Encrypted with AES-256-GCM and bound to the account. |
| Passwords | Argon2 hash only. |
| Wallet addresses | The public addresses you verified. Never private keys or seed phrases. |
| Order chat | Stored 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.
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.
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.
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.
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.
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.
- Use the contact form with the Security topic. Security reports are flagged for the team.
- Include the affected component, steps to reproduce and the impact you expect.
- 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.
- 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