> For the complete documentation index, see [llms.txt](https://pumpkindotfun.gitbook.io/pumpkin-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://pumpkindotfun.gitbook.io/pumpkin-docs/resources/lottery-verification-guide/random-number-verification.md).

# Random Number Verification

This document explains how to independently verify that the winner of a Pumpkin Lucky Draw was selected fairly, deterministically, and using ORAO VRF randomness.\
All verification can be done using public on-chain data from the fulfilled transaction linked in the dApp. Overview of the Verification Flow.

**To verify the random number used to select the winner, follow these steps:**

1. Locate the fulfilled VRF transaction
2. Extract the ORAO VRF randomness
3. Derive the raw random number used by the program
4. Apply modulo with total weight
5. Confirm the result matches the WinnerSelected event

### Step 1: Open the Fulfilled VRF Transaction

From the Pumpkin Platform (dApp), you are able to find the redirected to a Solana Explorer link pointing to the transaction where randomness was fulfilled.\
This transaction contains:

* An ORAO VRF fulfillment event `Fulfilled`
* The Pumpkin Lucky Draw program’s `WinnerSelected` event

### Step 2: Locate the ORAO VRF Fulfillment Event

In the transaction logs, find the event emitted by the ORAO VRF Callback program:

```
OraoVrfCb::events::fulfilled::Fulfilled
```

Inside this event, locate the field:

```
randomness: [u8; 64]
```

This is a 64-byte cryptographically secure random value generated and verified by ORAO VRF on-chain.

> This randomness is guaranteed to be unpredictable and tamper-proof by the ORAO VRF protocol.

### Step 3: Derive the Raw Random Number Used by the Program

The lucky draw program derives a raw random number by:<br>

1. Taking the first 16 bytes of the VRF randomness
2. Interpreting them as a little-endian unsigned 128-bit integer

This transformation is fixed and reproducible, allowing anyone to independently derive the same value from the on-chain randomness.

### Step 4: Apply Modulo with Total Weight

Each participant in the draw occupies a weighted range within:

```
[0, total_weight)
```

To select a winner fairly across all weights, the program computes:

```
winner_number = random_number % total_weight
```

Where:

* `random_number` comes from[ Step 3](#step-3-derive-the-raw-random-number-used-by-the-program)
* `total_weight` is the sum of all participant weights

### Step 5: Verify Against the `WinnerSelected` Event

In the same transaction, locate the Pumpkin Lucky Draw program event:

```
WinnerSelected
```

**This event includes:**

* `number` → the final winner number
* `random_number` → the raw u128 derived from randomness
* `total_weight` → total cumulative weight used
* `draw_count` → number of times draw completed
* `claim_deadline` → last valid claim time

**Verification checks confirm that:**

1. The `random_number` equals the u128 derived from `randomness[0..16]`
2. The `total_weight` matches the expected total
3. The following holds true:

```
winner_number == random_number % total_weight
```

If all checks pass, the random number selection is fully verified.

### Summary

**To verify the random number used in the draw:**

1. Open the fulfilled VRF transaction
2. Read `randomness: [u8; 64]` from the ORAO VRF fulfilled event
3. Convert `randomness[0..16]` to a little-endian u128
4. Compute `random_number % total_weight`
5. Confirm it matches `WinnerSelected.number`

If it matches, the draw result is provably fair and correct.
