Skip to content

Security rules for consumers ​

The VRF guarantees the result cannot be chosen. Your contract still has to avoid giving anyone a second chance. Most exploits of "random" games come from these mistakes.

1. Lock state when you request, not when you receive ​

Everything that the result affects (entries, bets, the participant list, a player's position) must be fixed before requestRandomWords. If a player can still change their bet after the request, they can wait until the result is visible in the mempool and react.

solidity
state = State.Drawing;              // lock first
requestId = s_coordinator.requestRandomWords(...);

2. Never re-request because of the outcome ​

No function should let anyone ask for new randomness for the same draw after seeing a result, including "retry" buttons, admin functions, or a new request when the callback "failed".

3. A cancelled request is a refund, never a reroll ​

A request can be cancelled after the timeout. The requester may already have seen the fulfilment transaction in the mempool before cancelling. If cancelling led to a fresh draw, they could keep cancelling until they liked the result. On timeout: refund (see Raffle) or keep the item locked. Never draw again.

4. Don't use the result in the same transaction it arrives ​

Do the heavy work in the callback or later, but don't let a third party trigger an action that reads the result and can revert depending on its value (they would revert on outcomes they dislike).

5. Callback failures are final ​

A reverting callback still consumes the request. Make the callback unable to revert (see Handling the callback).

6. Choose confirmations for the value at stake ​

A deep chain reorganisation could replace the request's block and therefore the seed. The oracle waits minimumRequestConfirmations before proving, and re-checks that the block is still canonical. Use more confirmations for higher stakes.

7. Bias from % ​

word % n is unbiased for practical purposes when n is small compared with 2²⁵⁶ (the bias is about n / 2²⁵⁶). For huge n, use rejection sampling.

8. Test the ugly paths ​

Use the mock coordinator to simulate: no answer (refund path), every possible outcome (fuzz the word), a reverting callback, and a late answer after a refund.

Testnet: PulseChain testnet v4. Unaudited software; do not use on mainnet yet.