Low Stakes

Simple randomness for everyday use

Security
7.5
1
Pay
10,000 PLS
2
Wait
~70-80 seconds
3
Use
Random number ready
TX
Request
BOT
Keeper
Past
+
Future
E
Entropy

Your randomness comes from many different block producers

Cost
10K
PLS
Wait Time
~75s
seconds
Difficulty
Easy
to integrate
Great For
NFT Traits
Character looks, colors
Game Items
Loot drops, rewards
Visual Effects
Art, animations
Fun Features
Non-money outcomes
Not For
Money Prizes
Use higher tiers
Betting
Needs more security
Auctions
Value at risk
Big Rewards
Worth manipulating

What's Included

Many Sources
Not just one block
Future Blocks
Can't be predicted
Spread Out
Samples across time
Transparent
Anyone can verify
For Developers

Integration Guide

Everything you need to add VEO to your smart contract

1Contracts

VE
VEO
Main contract
View →
VE
VEOKeeper
Helper queries
View →
VE
VEOViews
View functions
View →

2Quick Start

Solidity
// 1. Request randomness
uint256 price = veo.getPrice();
bytes32 requestId = veo.requestEntropy{value: price}();

// 2. Fulfill (run your own keeper, or wait for public keepers)
if (veo.isReadyToFulfill(requestId)) {
    veo.fulfillEntropy(requestId);
}

// 3. Get your random number
(bytes32 entropy, bool fulfilled, ) = veo.getEntropy(requestId);
require(fulfilled, "Not ready yet");
uint256 random = uint256(entropy);

3Working with External Keepers

Your app doesn't need to run its own keeper. Public keepers around the world can fulfill your requests and earn bounties. Here's how to detect when a keeper has fulfilled:

Your AppKeeper (anyone)VEO Contract
1.requestEntropy()→ returns requestId
2.Store requestId locally→ track in your app
3.Keeper calls fulfillEntropy()→ earns bounty
4.Poll getEntropy(requestId)→ detect fulfilled
5.Use entropy in your app→ done!
JavaScript / Frontend
// 1. Request entropy and capture the requestId from event
const tx = await veoContract.requestEntropy({ value: price });
const receipt = await tx.wait();

// Parse EntropyRequested event to get requestId
const event = receipt.logs.find(log => {
  try {
    return veoContract.interface.parseLog(log)?.name === "EntropyRequested";
  } catch { return false; }
});
const requestId = veoContract.interface.parseLog(event).args.requestId;

// 2. Store requestId locally (state, localStorage, database, etc.)
pendingRequests.add(requestId);

// 3. Poll for keeper fulfillment (every few seconds)
const pollForFulfillment = async () => {
  for (const requestId of pendingRequests) {
    const [entropy, fulfilled] = await veoContract.getEntropy(requestId);

    if (fulfilled) {
      // Keeper fulfilled it! Use the entropy
      console.log("Random number:", BigInt(entropy));
      pendingRequests.delete(requestId);

      // Use entropy in your app...
      onEntropyReady(entropy);
    }
  }
};

// Poll every 5 seconds
setInterval(pollForFulfillment, 5000);
Why track locally?
After a keeper fulfills, the request may be removed from the contract's pending list. Track requestIds yourself to detect fulfillment.
Keeper bounties
Keepers earn a bounty for fulfilling. Faster fulfillment = higher bounty. This incentivizes quick responses.

4All Functions

Request
getPrice() → uint256getBulkPrice(count) → uint256requestEntropy() → bytes32requestEntropyBulk(count) → bytes32[]
Fulfill (Keepers)
isReadyToFulfill(id) → boolfulfillEntropy(id)fulfillEntropyBulk(ids) → uint256
Get Entropy
getEntropy(id) → (bytes32, bool, uint8)getRequestCore(id) → (address, ...)
Refunds
refundRequest(id)refundRequestBulk(ids) → uint256refundMyRequests() → (uint256, uint256)

5Full ABI

VEO.sol
[
  "function getPrice() view returns (uint256)",
  "function getBulkPrice(uint256) view returns (uint256)",
  "function requestEntropy() payable returns (bytes32)",
  "function requestEntropyBulk(uint256) payable returns (bytes32[])",
  "function fulfillEntropy(bytes32)",
  "function fulfillEntropyBulk(bytes32[]) returns (uint256)",
  "function isReadyToFulfill(bytes32) view returns (bool)",
  "function getEntropy(bytes32) view returns (bytes32, bool, uint8)",
  "function getRequestCore(bytes32) view returns (address, uint256, uint256, uint8, uint8, bytes32)",
  "function refundRequest(bytes32)",
  "function refundRequestBulk(bytes32[]) returns (uint256)",
  "function refundMyRequests() returns (uint256, uint256)",
  "function userPendingRequests(address, uint256) view returns (bytes32)",
  "function userPendingRequestsLength(address) view returns (uint256)",
  "event EntropyRequested(bytes32, address, address, bytes32, uint256, uint256, uint256, uint8)",
  "event EntropyFulfilled(bytes32, address, uint256)",
  "event RequestRefunded(bytes32, address, uint256)"
]
VEOKeeper.solfor bots
[
  "function getGlobalFulfillable() view returns (bytes32[], uint256, uint256)",
  "function getGlobalFulfillablePaginated(uint256, uint256) view returns (bytes32[], uint256, uint256, uint256)",
  "function getPendingFulfillable(address) view returns (bytes32[], uint256, uint256)",
  "function getPendingRefundable(address) view returns (bytes32[], uint256, uint256)",
  "function getPendingStatus() view returns (bytes32[], bool[], bool[], uint256[], uint256)",
  "function canKeeperFulfill(address, bytes32) view returns (bool, bool, uint256, bool)",
  "function getBalanceBreakdown() view returns (uint256, uint256, uint256, uint256, uint256, uint256)"
]

Need more security? Check out Medium or High Stakes tiers.