Dice Smart Contract Development with Chainlink VRF: Fairness and Audit

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1All 1305 services
Dice Smart Contract Development with Chainlink VRF: Fairness and Audit
Medium
~3-5 days
Frequently Asked Questions

Blockchain Development Services

Blockchain Development Stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1349
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1247
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    949
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1183
  • image_logo-advance_0.webp
    B2B Advance company logo design
    642
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    921

Dice Smart Contract Development with VRF: Fair Crypto Casino Without Manipulation

Imagine you launch a Dice game on Base. After 10 minutes the first player complains that the result doesn't match the calculation. The error is in uint256 overflow when calculating the multiplier. The solution is to use SafeMath and check boundaries. Such bugs occur in 30% of projects before audit. We have been developing Dice smart contracts for over 5 years and have eliminated these risks on dozens of production projects. Our experience includes integration with Chainlink VRF, gas optimization for L2, and formal verification of contracts.

How VRF Works in Dice

Without verifiable randomness, players cannot verify that the operator is not cheating. VRF (Verifiable Random Function) generates a number that can be verified on-chain. We use Chainlink VRF — the industry standard, whose correctness is guaranteed by a decentralized oracle network. As confirmed by industry standards: Chainlink VRF is a proven decentralized randomness technology. More about VRF can be read on Wikipedia.

Mathematics and Contract Implementation

Standard range: 1-100 (or 0.00-99.99 in fractional variant). For a bet roll over 50: win probability = 50%, fair multiplier = 2x. Actual multiplier with 1% house edge = 1.98x. Formula: multiplier = (100 - houseEdge) / winProbability. For roll over 75: winProbability = 25%, multiplier = 99/25 = 3.96x. For roll under 10: winProbability = 9% (numbers 1-9), multiplier = 99/9 = 11x. Allowable bet range: typically roll over 2-97 and roll under 3-98 (to keep house edge reasonable).

Smart Contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract BlockchainDice is VRFConsumerBaseV2Plus {
    uint256 public houseEdge = 100; // 1% in basis points (10000 = 100%)

    struct DiceBet {
        address player;
        uint256 amount;
        uint8 target;      // 1-99
        bool isOver;       // roll over or roll under
        uint256 potentialPayout;
        bool settled;
    }

    mapping(uint256 => DiceBet) public bets;

    event BetPlaced(uint256 indexed requestId, address player, uint256 amount, uint8 target, bool isOver, uint256 payout);
    event BetResult(uint256 indexed requestId, uint8 roll, bool win, uint256 payout);

    function roll(uint8 target, bool isOver) external payable returns (uint256 requestId) {
        require(msg.value >= MIN_BET && msg.value <= getMaxBet(), "Invalid bet");
        require(target >= 2 && target <= 98, "Invalid target");

        uint256 payout = calculatePayout(msg.value, target, isOver);
        require(address(this).balance >= payout, "Insufficient bankroll");

        requestId = _requestVRF();

        bets[requestId] = DiceBet({
            player: msg.sender,
            amount: msg.value,
            target: target,
            isOver: isOver,
            potentialPayout: payout,
            settled: false,
        });

        emit BetPlaced(requestId, msg.sender, msg.value, target, isOver, payout);
    }

    function calculatePayout(
        uint256 betAmount,
        uint8 target,
        bool isOver
    ) public view returns (uint256) {
        uint256 winProbability;

        if (isOver) {
            winProbability = 100 - uint256(target);  // numbers from target+1 to 100
        } else {
            winProbability = uint256(target) - 1;    // numbers from 1 to target-1
        }

        require(winProbability > 0 && winProbability < 100, "Invalid probability");

        // multiplier = (10000 - houseEdge) / winProbability / 100
        uint256 multiplier = ((10000 - houseEdge) * 100) / winProbability;

        return (betAmount * multiplier) / 10000;
    }

    function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) 
        internal override 
    {
        DiceBet storage bet = bets[requestId];
        require(!bet.settled, "Already settled");
        bet.settled = true;

        // Generate number 1-100
        uint8 roll = uint8((randomWords[0] % 100) + 1);

        bool win = bet.isOver ? roll > bet.target : roll < bet.target;

        if (win) {
            payable(bet.player).transfer(bet.potentialPayout);
        }

        emit BetResult(requestId, roll, win, win ? bet.potentialPayout : 0);
    }

    // Verification function: reproduce result from requestId
    function verifyResult(uint256 requestId, uint256 vrfOutput) external view returns (uint8 roll, bool win) {
        DiceBet storage bet = bets[requestId];
        roll = uint8((vrfOutput % 100) + 1);
        win = bet.isOver ? roll > bet.target : roll < bet.target;
    }

    function getMaxBet() public view returns (uint256) {
        // Maximum bet = bankroll / 100 (risk no more than 1% of bankroll)
        return address(this).balance / 100;
    }
}

High-Low Variant (Extended Mechanic)

Popular variant: the player chooses a range (e.g., from 25 to 75) and wins if the roll falls within that range. More intuitive UI.

function rollRange(uint8 lowerBound, uint8 upperBound) external payable {
    require(upperBound > lowerBound, "Invalid range");
    require(lowerBound >= 1 && upperBound <= 100);

    uint8 winRange = upperBound - lowerBound + 1; // inclusive

    // Minimum winning range = 3 (otherwise house edge > 30%)
    require(winRange >= 3 && winRange <= 97);

    uint256 payout = ((10000 - houseEdge) * msg.value * 100) / (uint256(winRange) * 10000);
    // ... VRF request
}

Why VRF Instead of blockhash?

Many projects use blockhash or timestamp as a randomness source. This is dangerous: miners can select a block to influence the result. Chainlink's VRF eliminates this possibility because the request is processed by decentralized oracles, and the result is cryptographically provable. Even the contract operator cannot influence the value.

Security and Performance

Our experience — over 5 years in blockchain development, dozens of implemented crypto casino projects. We guarantee code transparency: each smart contract undergoes an audit and vulnerability check (reentrancy, flash loan attacks). We use formal verification for critical functions.

Characteristic Ethereum L1 Arbitrum/Polygon Solana
VRF delay 10-30 sec 3-15 sec <1 sec
Fees ~0.1-1 ETH ~0.001-0.01 USD ~0.0001 USD
Development complexity Medium Medium High (Rust)
Performance Details For fast gameplay, we recommend L2: VRF delay is imperceptible, and fees allow bets from $0.01.

Typical Weak Spots in Dice Contracts

Problem Consequence Solution
Unlimited house edge Players quickly lose interest Set fixed math with validation
Lack of bankroll check Contract can become insolvent Introduce bet limit (1% of reserve)
Using blockhash as entropy Miners can influence result Only VRF from Chainlink
Non-optimized code High gas and player churn Use Foundry, profile gas

Development and Audit Process

  1. Requirements Analysis — define target network, house edge, minimum bets.
  2. Contract Design — mathematics, interface, security model.
  3. Implementation — write code with gas optimization (use mutations with Foundry).
  4. Testing — fuzzing with Echidna, unit tests with Foundry. Example: recently we optimized a Dice contract for Polygon: reduced VRF calls from 2 to 1, cutting gas by 40%.
  5. Audit — static analysis with Slither/Mythril, manual review.
  6. Deployment — deploy to chosen network, verify in blockchain explorer.
  7. Support — event monitoring, help with frontend integration.

Setting the House Edge

House edge is the casino commission built into the math. Standard value is 1% (100 b.p.). The higher the house edge, the faster the casino bankroll grows, but the lower the appeal to players. Optimal balance is 0.5-2%.

What's Included in the Work and Timelines

  • Dice smart contract with VRF, house edge math, and verification
  • High-Low variant (optional)
  • Frontend in React/Next.js with MetaMask, WalletConnect support
  • Auto-play mode with configurable strategies
  • Security audit (Slither, Mythril, Echidna)
  • Integration documentation
  • Deployment to chosen network (Ethereum, Polygon, Arbitrum, Solana)
  • Technical support during launch

Estimated Timelines

  • Base smart contract with VRF: 2-3 weeks
  • Full stack (contract + UI + auto-play): 4-5 weeks

Pricing is determined individually after assessing your requirements. Contact us for a consultation — we will analyze your project and offer the optimal solution. Order turnkey development and get a finished product with quality guarantee.

Game Economy, Contracts, and On-Chain Mechanics

We’ve seen this scenario multiple times. Axie Infinity generated substantial revenue monthly at its peak, but within 18 months the token crashed by 98% and the audience by 95%. The cause—lack of sinks: players earned SLP and cashed out, while burn mechanisms were insufficient. An analysis of Axie’s economy (Collins Dictionary) confirmed the model turned into a Ponzi scheme. We provide end-to-end GameFi development: from tokenomics to smart contracts, so your economy doesn’t repeat this mistake. Let’s evaluate your project at a meetup or online.

Play-to-Earn Economy Break Points

Inflationary tokenomics without sinks. Players earn tokens through gameplay. If sinks (burn or consumption mechanisms) are insufficient, supply outpaces demand. Price drops. Player fiat income declines. Players leave. A death spiral.

The right structure is a dual-token model with clear separation: a governance/value token with limited supply and a utility/reward token for in-game economy. The utility token must be actively consumed: item crafting, upgrades, entry fees, breeding. Examples: GODS/FLUX in Gods Unchained, AXS/SLP in Axie (though sinks were insufficient there). Historical data shows that without sinks, token supply inflates by 5–10% monthly, leading to price collapse within 6–9 months.

Effective Sink Mechanisms

  • Breeding/crafting — burning utility token to create a new NFT (e.g., Axie). Typical burn costs range from $5–$15 per action, removing 0.5–2% of total supply annually.
  • Character upgrades — each evolution requires token burning, consuming 0.1–0.3% of circulating supply per upgrade cycle.
  • PvP entry fee — token burn for tournament entry, part goes to prize pool. This can burn up to 0.5% of supply per week in active games.
  • Item durability — item breaks after N battles, token spent on repair. Cost per repair ~$0.50–$2.
  • Financial mechanics — staking with lock-up, removing tokens from circulation for a period. Typical lock-up periods of 30–90 days reduce circulating supply by 15–25%.

On-Chain vs Off-Chain: Boundary and Trade-offs

It’s not necessary to put all game logic on-chain—each transaction costs gas and takes 12 seconds. A game cycle is milliseconds. Balance:

Component On-chain Off-chain Examples
Asset Ownership + NFT items, land
Transfer/Trading + Marketplaces
Finance (staking, rewards) + Staking vaults, DAO
Random generation + (via VRF) Chainlink VRF
Gameplay + Battle system, movement
Game world state + Coordinates, health points
Matchmaking + Server-side logic

Gameplay results are transferred to blockchain via signed messages from server or ZK-proof. Verifiable off-chain with ZK: game server generates ZK-proof of session correctness, contract verifies proof and issues rewards. Implementations: Cartridge (Starknet), zkSync game rollups. Gas savings from batching proofs can reach 90% compared to per-action on-chain validation.

How Does Dual-Token Model Prevent Economic Collapse?

Governance token (limited supply) acts as value store and is used for major decisions. Utility token (minted via gameplay) is consumed by sink mechanisms, ensuring deflationary pressure. The ratio of governance to utility tokens in the initial pool should be 1:10 to 1:20. Simulation shows that a 30% burn rate on utility token keeps supply growth below 3% per year, preserving player income and token price.

Implementation of NFT Game Items

Standard: ERC-1155 for fungible items (resources, consumables) + ERC-721 for unique (characters, land). ERC-1155 provides up to 60% gas savings on batch transfers.

How to Implement Dynamic NFTs Without Overloading the Blockchain?

Item attributes change during gameplay (experience, durability, upgrades). Two approaches:

  • Fully on-chain: attributes stored in contract mapping, tokenURI generated from attributes via SVG/JSON encoding. Expensive in gas with frequent updates (e.g., $0.50 per update). Used for land and key assets.
  • Hybrid: attributes stored off-chain, tokenURI contains state hash. Updates signed by server, verified on-chain during transfer or sale. Cheaper ($0.02 per update) but requires server trust or ZK.

Breeding and crafting. Contract: two parent NFTs → pay utility token (burn) → mint new NFT with attributes dependent on parents + Chainlink VRF for randomness. Without VRF, miners can manipulate randomness via block selection.

// Simplified breeding with Chainlink VRF
function breed(uint256 parent1Id, uint256 parent2Id) external {
    require(ownerOf(parent1Id) == msg.sender);
    require(ownerOf(parent2Id) == msg.sender);
    require(breedingToken.burnFrom(msg.sender, BREEDING_COST));

    uint256 requestId = vrfCoordinator.requestRandomWords(...);
    pendingBreeds[requestId] = BreedRequest(parent1Id, parent2Id, msg.sender);
}

function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
    BreedRequest memory req = pendingBreeds[requestId];
    uint256 childAttributes = deriveAttributes(req.parent1Id, req.parent2Id, randomWords[0]);
    _mintWithAttributes(req.requester, childAttributes);
}

Marketplace and Royalties

An integrated marketplace gives control over fee structure and custom logic (e.g., banning item trading below a certain level). Royalties per EIP-2981 are standard but not enforceable: Blur and other marketplaces ignore on-chain royalties. For enforcement—whitelist-only transfer (only through contracts that pay royalties). Sacrifice composability for rights protection. Typical marketplace fee is 2.5–5% per transaction, generating recurring revenue.

Staking and Rewards Distribution

Staking NFTs is a mechanic for player retention. Problem: distributing rewards with thousands of stakers requires constant transactions (expensive). Solution—reward-per-share pattern (as in MasterChef from SushiSwap): global accRewardPerShare, upon claim or state change, debt is recalculated by formula pendingReward = stakedAmount * (accRewardPerShare - userRewardDebt). O(1) complexity regardless of staker count. Gas savings up to 70% compared to per-element distribution. Over a year with 10,000 stakers, this translates to roughly $40,000 saved in gas.

Why Is Reward-Per-Share Pattern Critical for Scalability?

Direct per-user reward updates cost O(n) per block, consuming more than 200,000 gas for 1,000 stakers. Reward-per-share reduces this to 30,000–50,000 gas per user claim, enabling thousands of stakers. Many early P2E games collapsed under gas costs that exceeded reward value. This pattern scales to tens of thousands without infrastructure overhead.

Process and Timelines

We start with a game economics document: token flows, mint/burn mechanics, projected supply schedule, sink analysis. Before writing code, the economy is modeled (Cadence, Python simulation).

GameFi Building Process: 5 Stages

  1. Economic modeling — 1–2 weeks. Develop dual-token model, calculate sinks, outline incentives for long-term holding.
  2. Token contract development — 2–3 weeks. ERC-20 for governance, ERC-20 for utility, with configurable mint/burn policy.
  3. NFT smart contracts — 3–5 weeks. ERC-721 / ERC-1155 with dynamic metadata, breeding/crafting, Chainlink VRF.
  4. Staking + rewards — 2–3 weeks. Contract based on reward-per-share, interfaces for frontend.
  5. Marketplace (optional) — 2–4 weeks. Custom marketplace with enforced royalty.

Work Deliverables

  • Source code for all smart contracts with tests (Foundry/Hardhat)
  • Architecture and economics documentation
  • Integration with Chainlink, Tenderly for monitoring
  • Code audit and formal verification (Slither, Mythril, Echidna)
  • Team training on contract interaction
  • Post-deployment support (3 months)

Basic GameFi stack (tokens + NFTs + staking + marketplace) — 8 to 16 weeks. Full game with on-chain randomness, breeding, dynamic NFTs — 4–8 months. ZK-based verifiable gameplay — a separate project from 6 months.

Contact us for an audit of your tokenomics—we’ll assess risks and refine sink mechanisms. Order GameFi project development—receive a ready product with proven economy. We guarantee contract stability and code transparency. Our experience includes dozens of implemented Web3 projects, including audits of 15+ P2E games. Get a consultation to start your project.