> For the complete documentation index, see [llms.txt](https://docs.rolly.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rolly.io/tech-specs.md).

# Tech Specs

Under the hood of Rolly. Every part that matters is open to verify.

<figure><img src="https://3451128504-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHENicywcSMrapj9qj90E%2Fuploads%2FC2TobyEgGHNN5EMVteda%2F4%20(1).png?alt=media&amp;token=993c446b-abce-4d12-a0e7-8803f60b71d3" alt=""><figcaption></figcaption></figure>

#### **Non‑custodial**

Player funds are held in a smart contract on Arbitrum, not in the operator accounts. Every deposit and withdrawal is recorded onchain. If the platform stops the operation, players can withdraw their funds directly from the blockchain via a **Force Exit** mechanism.&#x20;

Deposit amounts are stored in each user’s state inside a Merkle Tree and protected by a ZK-proof. The operator cannot appropriate or alter a deposit because any balance change must be proven in the ZK circuit and verified onchain.

***

#### **ZK Verified Originals**

**Fair by math, not by promises**

**ZK (zero-knowledge proof)** uses math to prove a calculation was done correctly. Every bet in ZK Verified Originals is covered by such a proof, and a smart contract on Arbitrum checks it automatically. You don't have to take our word for it, or check anything by hand.

Under the hood, Rolly runs as a rollup (appchain). Your bets go to a sequencer that validates them, groups them into batches and publishes them, with your balances, to Arbitrum. Building our public code produces a verification key, stored in our treasury contract on Arbitrum.&#x20;

That contract holds players' funds and accepts only proofs made by that exact code. Change a single byte, and the key no longer matches, so no balance can change.&#x20;

We can't touch the code, the random number or the result. You can build the code yourself and compare its key with the one in the treasury contract.

{% hint style="info" %}
For what ZK Verified means for players and how to verify any bet yourself, see [ZK Verified](https://docs.rolly.io/verify-onchain/zk-verified).
{% endhint %}

***

#### **How every bet is verified**

{% stepper %}
{% step %}
**We lock our seed**

We lock our seed first. Before your bet, we fix our server seed and show you its hash. After the bet, the seed goes into a batch that is recorded on Arbitrum, so it can’t be changed.
{% endstep %}

{% step %}
**Add your seed and make a bet**

Your seed is created in your browser, and your bet is signed with your personal key. The key is created from your wallet and is never sent to us, so no one can place a bet in your name or change it afterwards. The result depends on both seeds, so no one can pick it in advance.
{% endstep %}

{% step %}
**Blockchain checks everything**

The proof confirms that our seed matches the hash, the random number comes from both seeds (server and user), and your win and balance follow the game rules exactly. One cent off, and the contract rejects it.
{% endstep %}
{% endstepper %}

#### **Why it's better than the usual provably fair**

* **More than the random number.** Elsewhere you can check only the random number. We prove the whole bet: random number, win and balance, all tied together by the code.
* **Every bet, automatically.** Elsewhere you verify by hand, and almost nobody does. Here every bet of every player is checked cryptographically with ZK proofs and published to Arbitrum.
* **Checked by the blockchain, not the casino.** A public smart contract does the check and accepts only a valid proof.
* **Only you can change your seed.** Your current server seed is recorded onchain. A server restart, crash or database failure can't change it, and neither can we as the operator. Only you can, by sending a transaction signed with your key.
* **Only you can change your balance.** Every balance change is a transaction in our rollup, and every transaction must be signed with your key. We can't just edit your balance on the server.

#### **Seeds**

* **Server seed hash.** Locked before you bet. We can't change it after you see this hash.
* **User seed.** Created in your browser. A new seed is generated automatically before each bet.

***

#### **Check it yourself**

{% hint style="success" %}
**Every bet is checked automatically.** A smart contract on Arbitrum accepts each batch of bets only with a valid ZK proof.
{% endhint %}

**1. Place a bet:** its server seed is revealed right after.

<div data-with-frame="true"><figure><img src="https://3451128504-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHENicywcSMrapj9qj90E%2Fuploads%2FqtQcb3D1AmLIXL7yUOB1%2FScreenshot%202026-10-26%20at%2019.35.08.png?alt=media&amp;token=de553d08-f609-49ab-aa46-ec05f34de6cc" alt="" width="375"><figcaption></figcaption></figure></div>

**2. Open it in Rolly Explorer:** from your bet history or by bet ID.

<div data-with-frame="true"><figure><img src="https://3451128504-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHENicywcSMrapj9qj90E%2Fuploads%2FYB5QNdHYpxMWgZZTaPmn%2FScreenshot%202026-10-26%20at%2019.36.36.png?alt=media&amp;token=8b90c90b-5ca1-4556-ac92-bb4246ae53d8" alt="" width="375"><figcaption></figcaption></figure></div>

**3. Press Verify Fairness:** the checks run in your browser.

<div data-with-frame="true"><figure><img src="https://3451128504-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHENicywcSMrapj9qj90E%2Fuploads%2F0PJ5msJfN7YpWKA4wfaP%2FScreenshot%202026-10-26%20at%2019.40.54.png?alt=media&amp;token=2bbd13b6-303b-4113-b5d4-8e8e3eadad31" alt="" width="375"><figcaption></figcaption></figure></div>

<div data-with-frame="true"><figure><img src="https://3451128504-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHENicywcSMrapj9qj90E%2Fuploads%2FpL3dXKU1BVfCOsf9SAfH%2FScreenshot%202026-10-26%20at%2019.41.27.png?alt=media&amp;token=cc9c227a-0fc8-48d1-a95c-48e1d9405dba" alt="" width="375"><figcaption></figcaption></figure></div>

***

#### **What gets checked**

| Check     | What it confirms                            | Formula                                          |
| --------- | ------------------------------------------- | ------------------------------------------------ |
| Random    | Calculated from both seeds, ours and yours. | `Random = Poseidon2(Server Seed ‖ User Seed)`    |
| Seed hash | Matches the hash shown before the bet.      | `Hash = Poseidon2(Server Seed)[0..3]`            |
| Payout    | Matches the payout table exactly.           | `Win = compute_payout(Random, Bet, Game Params)` |

{% hint style="info" %}
[See the payout tables in the repository ↗](https://github.com/rolly-io/games-core/tree/main/src)
{% endhint %}

***

#### **Don't trust the explorer either?**

Every bet page has a JS Verification Code block. Copy it and run it on your own machine with `@rolly-dev/wasm-signer` (npm).

***

#### **Proof of Reserves**

The platform’s Total Liabilities to players are computed inside the ZK circuit and published onchain with each batch.&#x20;

Anyone can compare the smart contract balance to the published Total Liabilities to confirm the platform’s solvency in real time.

***

#### **Technical Summary**&#x20;

* Bets are processed offchain, grouped into blocks, and blocks are aggregated into batches.
* Each transaction is proven with an individual ZK-proof (Plonky2 on the Goldilocks field). Proofs are then recursively aggregated into a single compact PLONK proof that is verified onchain (Arbitrum).
* All player states are stored in a Merkle tree of depth 28 (supports up to 268M users) using Poseidon2 hashing.
* Up to 20 currencies are supported concurrently (ETH, USDT, USDC, BNB, SOL, TRX, etc.).
* Players authenticate bets via session keys, no per‑transaction wallet confirmation required.
* All bets, deposits, withdrawals, and payouts are visible in the public Rolly Explorer, with every transaction visible in real time.
