Security

Why your money cannot be taken or lost

Stablevoy never holds funds. Payments go to one-time contract addresses that can only forward money to your wallet. Here is exactly how that works, what we control and what we do not, so you can check it instead of trusting us.

What the contracts guarantee

Destinations are fixed in the address itself

A deposit address is computed from the invoice, your payout wallet and the fee rate. Whatever arrives there can only go to that wallet and to the fee recipient written into the factory at deployment. Nobody can change either one afterwards, including us.

No owner, no admin, no upgrades

The factory and the forwarders have no owner key, no pause switch and no upgrade path. There is no function that moves funds anywhere else, so there is nothing to steal a key for.

The fee is capped in code

The factory refuses any fee above its built-in cap of 2%, and each invoice commits to its own fee rate when the address is created. The split happens on-chain: the fee rounds down, the rest goes to you.

Anyone can push the funds to you

Forwarding is permissionless. Our service normally does it and pays the network fee, but you, the buyer or anyone else can call the same public function. Calling it can only deliver the money to its fixed destinations.

Wrong token on the right network is not lost

A forwarder can send any token or the native coin it holds, not only the one on the invoice. If a buyer sends another token on the same network, it is not counted towards the invoice, but it is not lost either: the same public function forwards it to your wallet (see the recovery guide).

Every sender is checked against sanctions lists

Before a confirmed payment counts, the address it came from is checked against the OFAC list of sanctioned crypto addresses. A match puts the invoice on hold and you get a webhook. If the list cannot be read or is out of date, the payment waits instead of passing unchecked. The site and the API are not available from sanctioned countries and occupied regions.

The buyer checks the address before paying

The payment page recomputes every deposit address in the buyer's browser from public data and the contract rules. If an address does not match, the page refuses to show payment details.

What we run, and what that means

We run the API that creates invoices, the service that watches the networks and the service that forwards confirmed payments and pays the network fee for it. If all of it stopped, payments already made would stay on their deposit addresses, still bound to your wallet, and you could forward them yourself with the recovery guide. Everything that recovery needs (the invoice salt, your payout address and the fee rate) is also in every webhook we send you.

Changing your payout address requires a fresh signature from your login wallet and only affects new invoices: an address that already exists keeps paying to the wallet it was created for.

A payment put on hold by the sanctions check stays bound to your wallet like any other: the hold stops the order from being marked paid, it cannot send the money anywhere else.

How the code is checked

  • The contracts are small: a factory and a forwarder, under 200 lines together, built on OpenZeppelin libraries.
  • 42 contract tests with 100% line and branch coverage of both contracts, including fuzz tests of the fee split and the fee cap.
  • Static analysis with Slither and Aderyn on every change.
  • The source of every deployed contract is published on the block explorer, so anyone can compare it with the code that runs.
No external audit has been done yet. We will publish the report here when one is. Until then, the code is open for anyone to read on the explorer.

Contracts used by this deployment

Read live from our API. Each link opens the contract on the network's block explorer.

Loading the contract list...