Skip to main content
Your callback is the trust boundary between roll.codes and your contract logic. Keep it small, explicit, and defensive.

Required checks

1

Authorize the caller

Only accept callbacks from the configured coordinator address.
2

Look up request state

Load the record for requestId and reject unknown requests.
3

Prevent duplicate settlement

Reject callbacks for requests you have already settled.
4

Settle outcome deterministically

Derive the result, persist state, and avoid unnecessary external calls.

Minimal guard pattern

function randomNumberCallback(uint256 requestId, uint256 randomNumber) external {
    if (msg.sender != address(vrfSystem)) revert Unauthorized();

    Pending storage request = pendingByRequestId[requestId];
    if (request.player == address(0)) revert RequestNotFound(requestId);
    if (request.settled) revert AlreadySettled(requestId);

    request.settled = true;
    request.randomNumber = randomNumber;
}

What to avoid

  • callbacks that make unrelated external calls before marking state
  • large amounts of branching that increase revert risk
  • deriving user-visible state before verifying the request exists
  • relying on frontend state instead of contract state during settlement

Verification checklist

  • The deployed coordinator address matches the network you are using.
  • Unknown request IDs revert.
  • Duplicate settlement reverts.
  • The callback succeeds reliably within the gas supplied by the delivery transaction.

Coordinator reference

Look up the request function, requestFee() call, and callback interface.

Integration pattern

Start from a complete example that already applies these checks.

Quickstart

Use the hosted-coordinator setup flow before you harden your callback.
Last modified on March 9, 2026