Knowledge Base / Web3 & Crypto
Industry Standard

NFT Fairness: Don't Let Predictable RNG Ruin Your Drop

Jan 2026

1. The Adversarial Nature of the "Fair Launch"

In the nascent yet hyper-financialized ecosystem of Web3, the term "Fair Launch" has mutated from a technical descriptor into a marketing shibboleth. Ideally, it signifies a distribution mechanism where every participant has an equal, unbiased probability of acquiring a desirable asset, unencumbered by insider knowledge, pre-computations, or algorithmic manipulation. However, the reality of the Ethereum Virtual Machine (EVM) and other deterministic state machines is starkly different. For the uninitiated developer or the idealistic digital artist, the blockchain appears to be a sanctuary of immutability and trust. For the adversarial actor—the sniper bot developer, the MEV (Maximal Extractable Value) searcher, or the rogue validator—it is a deterministic playground where "luck" is a variable that can be calculated, simulated, and exploited for profit.

The fundamental disconnect lies in the understanding of Entropy. In the physical world, randomness is ubiquitous—thermal noise, radioactive decay, atmospheric turbulence. In the digital ledger of a blockchain, true randomness is an anomaly, a paradox that the consensus mechanism actively suppresses to ensure that every node reaches the exact same state. When a smart contract engineer naively imports the concepts of randomness from Web2—relying on system clocks or simple linear congruential generators—into the adversarial environment of Web3, they do not merely introduce a software bug; they introduce an economic vulnerability that can drain millions of dollars of value from a collection in mere seconds.

This report serves as a technical autopsy of failed randomness, a theoretical treatise on cryptographic fairness, and a practical manual for implementing the "TrueRNG" standard. We will dissect the mathematics of shuffling, the specific vulnerabilities of on-chain entropy sources like PREVRANDAO, and the definitive solution offered by Provenance Hashes and Commit-Reveal schemes. We address the Web3 Developer, the Project Founder, and the Digital Artist with a singular, urgent message: stop trusting luck. Trust cryptography.

1.1 The High Stakes of Rarity and Metadata Sniping

Non-Fungible Tokens (NFTs) derive a significant portion of their market value not just from aesthetic utility, but from Rarity. The market creates a steep power law in valuation based on attribute scarcity. Whether utilizing "Trait Rarity" (the scarcest single attribute), "Average Trait Rarity," or "Statistical Rarity" (multiplying trait probabilities), the economic divergence is massive. A "Floor" NFT might trade for 0.1 ETH, while a "Legendary" 1-of-1 from the same collection trades for 100 ETH or more.

This 1000x price multiple creates a massive incentive for Metadata Sniping. If an adversarial actor can predict which unminted Token ID contains a Legendary trait, they can selectively mint only the high-value items, leaving the "commons" for the general public. This destroys the economic integrity of the collection, alienates the community, and arguably constitutes fraud if the "random" distribution was promised.

The mechanisms for calculating rarity have become standardized, allowing bots to automate this valuation process in milliseconds.

  • Trait Rarity Ranking: Ranks NFTs based on the rarity of their rarest trait. This is a fragile metric but often the first used by snipers.
  • Statistical Rarity: Calculates the overall probability of an asset's existence by multiplying the probabilities of its individual traits (Ptotal = Ptrait1 × Ptrait2 × ...). This provides a more granular "score" that bots use to rank unrevealed collections if metadata leaks.

If the randomness generation (RNG) is predictable, the rarity distribution is broken. A 1% chance of a rare item becomes a 100% chance for an attacker with a sniper bot.

2. Anatomy of a Heist: The Meebits Exploit & Metadata Sniping

To understand the necessity of cryptographic fairness, we must first analyze the failure modes of the past. The Meebits launch by Larva Labs (creators of CryptoPunks) in May 2021 remains the ur-example of a catastrophic fairness failure driven by predictable entropy.

2.1 The Meebits Vulnerability: Optimistic UI vs. Pessimistic Contracts

The Meebits collection consisted of 20,000 unique 3D voxel characters. 9,000 of these were sold via a Dutch Auction, while the remainder were free to claim for CryptoPunks and Autoglyphs owners. The critical flaw lay in how the "random" ID assignment was handled during the minting process.

The Meebits smart contract allowed users to mint IDs sequentially. However, the metadata—defining which ID possessed which traits—was effectively public or deterministically generated on-chain in a manner that could be verified during the transaction execution. The contract utilized a pseudo-random number generator that relied on on-chain variables accessible to the minting transaction itself.

2.2 The Attack Vector: Reverting for Rarity

An attacker, identified in the community as "0xNietzsche," constructed a malicious smart contract to exploit this determinism. The attack leveraged the atomicity of Ethereum transactions. In Ethereum, a transaction is atomic; it either executes completely, changing the state, or it fails (reverts) entirely, rolling back all state changes while still consuming gas fees.

The attack flow was methodical and ruthless:

  1. Contract Deployment: The attacker deployed a custom "Exploit Contract."
  2. Conditional Minting: This contract was programmed to call the Meebits.mint() function.
  3. Introspection: Immediately after receiving the token ID, the exploit contract checked the specific traits or the ID of the minted Meebit within the same transaction. Because the metadata generation logic was accessible, the contract could determine if the minted asset was a "Visitor" (ultra-rare), a "Skeleton," or a common human.
  4. The Kill Switch:
    • If Common: The contract executed a revert() command. This cancelled the mint. The attacker paid the gas fees for the computation but did not pay the mint price (or wasted the mint opportunity) for a low-value asset.
    • If Rare: The contract completed execution, securing the asset.

2.3 The Economic Calculus of the Exploit

The attacker spammed the Ethereum network with these conditional transactions. They effectively "re-rolled" the dice thousands of times. While the cost of gas was high—estimated at approximately $20,000 per hour in failed transaction fees—the expected value of a successful "hit" dwarfed this expense.

The attacker ultimately succeeded in minting Meebit #16647, a rare "Visitor" type. This asset was subsequently sold for 200 ETH, which was approximately $700,000 USD at the time. The profit margin was astronomical, turning a five-figure gas expense into a six-figure windfall.

This exploit demonstrated a fundamental law of Web3 security: If the cost of the attack (gas) is less than the potential profit (arbitrage value), the attack will happen.

2.4 Broader Implications: Metadata Sniping

While the Meebits exploit involved on-chain re-rolling, Metadata Sniping is a broader and more insidious class of attack that affects projects even without on-chain metadata generation vulnerabilities. It occurs when the mapping of TokenID to Image/Traits is leaked or deducible before the mint is complete.

In a typical vulnerable scenario:

  1. Premature Upload: A project uploads 10,000 JSON files to IPFS (InterPlanetary File System). The developers intend to keep the IPFS hash secret until the "Reveal."
  2. Leakage: If the developers set the baseURI in the smart contract to the IPFS directory during the mint (to allow instant reveals), or if the directory hash is leaked via a side channel, the entire metadata set becomes public.
  3. Analysis: Sniper bots download all 10,000 JSON files. They calculate the "Statistical Rarity" of every single ID. They build a database: ID #4055 is the "Golden Ape," ID #102 is a "Zombie," etc.
  4. Execution: The bot monitors the smart contract's totalSupply variable. As the mint count approaches 4054, the bot prepares a transaction. The moment the counter hits 4054, the bot broadcasts a mint transaction with a massive gas tip (Priority Fee) to ensure they are the one to mint ID #4055.

This creates a "Rigged/Sniped" distribution. The rarest items are captured by sophisticated actors with algorithmic advantages, while the community is left with the "floor" items. This is not a lottery; it is an information asymmetry game where the retail user is the yield.

3. The Trap: Insecure Sources of Entropy

The root cause of the Meebits exploit and metadata sniping is the reliance on insecure sources of entropy (randomness). To prevent these attacks, we must understand why common sources of randomness fail in the adversarial context of blockchain.

1. The On-Chain Flaw

Developers often use block.timestamp or block.difficulty as seeds.

The Attack: Miners control these variables. A miner can discard blocks where they don't mint a rare NFT, effectively re-rolling the dice until they win.

2. The Off-Chain Flaw

Using simple Math.random() in a generation script.

The Attack: If the metadata API is public before the reveal, snipers can query /api/1, /api/2, etc. They map the rarity to the ID and only send a transaction for ID #42 (the Legendary), leaving the Common ID #41 for you.

3.1 The Deterministic Dilemma of the EVM

The Ethereum Virtual Machine is a deterministic state machine. For the network to reach consensus, every node must execute every transaction and arrive at the exact same result. If a contract used a true random number generator (like atmospheric noise), different nodes would produce different states, and the chain would fork immediately. Therefore, true randomness is impossible inside the EVM without external inputs (Oracles).

Developers, often migrating from Web2 contexts, reach for pseudo-random variables available within the block header. This is a fatal error.

3.2 On-Chain Flaws: The Miner's Dice

The two most abused variables for on-chain randomness are block.timestamp and block.prevrandao (formerly block.difficulty).

3.2.1 block.timestamp Manipulation

The variable block.timestamp returns the Unix timestamp of when the block was mined. Naive implementations often use modulo arithmetic:

R = block.timestamp (mod n)

This is fundamentally insecure for two reasons:

  1. Predictability: An attacker knows the current time. They can predict the timestamp of the next block within a narrow window (usually ± 12 seconds). They can pre-calculate the result R and only submit their transaction if the timestamp yields a favorable outcome.
  2. Miner Manipulation: Miners (and now Validators in PoS) set the timestamp of the block they propose. While the protocol enforces that the timestamp must be greater than the previous block and within a certain bound of "real time," validators have latitude. If a validator detects that setting the timestamp to T results in them winning a valuable NFT (or facilitating a bribe from a sniper), they can and will choose that timestamp.

3.2.2 The PREVRANDAO and the "Last Revealer" Problem

With Ethereum's transition to Proof of Stake (The Merge), the DIFFICULTY opcode (0x44) was repurposed to PREVRANDAO (EIP-4399). This returns the output of the Randomness Beacon from the Beacon Chain. While this is a source of entropy superior to difficulty, it is still biasable.

The vulnerability is known as the Last Revealer Problem.

  • Mechanism: The randomness is derived from the aggregation of signatures (RANDAO) from validators in an epoch.
  • The Attack: The validator scheduled to propose the block knows the current PREVRANDAO accumulator value. They also know their own contribution. They can calculate the final random number that will result if they propose the block.
  • Biasability: If the result is unfavorable (e.g., they lose a high-stakes gamble or miss a rare NFT mint), the validator can choose not to propose the block (skip their slot). This forces the network to use the randomness from the previous state.
  • 1-Bit Influence: This gives the validator a "1-bit influence"—they effectively have a binary choice between two possible random numbers. In a high-value mint, this 1-bit influence is enough to skew the odds significantly in their favor.
  • Cost: The cost to the validator is the loss of the block reward (approx. 0.04 ETH). If the NFT is worth 10 ETH, skipping the block is a rational economic decision.

3.3 Off-Chain Flaws: The Math.random() Disaster

Moving randomness off-chain (generating the sequence on a server before the mint) eliminates miner manipulation but introduces the vulnerabilities of Pseudo-Random Number Generators (PRNGs).

JavaScript's standard Math.random() is not Cryptographically Secure (CSPRNG).

  • Algorithm: Most modern JavaScript engines (like V8 in Node.js and Chrome) implement Math.random() using xorshift128+. This is a fast, non-cryptographic algorithm designed for simulations, not security.
  • State Leakage: xorshift128+ has a relatively small internal state (128 bits). If an attacker can observe a sequence of outputs—for example, the traits of the first 50 minted NFTs—they can use a constraint solver (like Z3) or simple linear algebra to recover the internal state of the generator.
  • Forward Prediction: Once the internal state is recovered, the attacker can predict every subsequent number the generator will produce. They possess the "God View" of the entire remaining mint sequence.

Visualizing the Trap: Imagine the "Mempool" as a dark forest.

  1. Surveillance: A Sniper Bot sits in the mempool, monitoring pending transactions.
  2. Simulation: It simulates the execution of a Mint transaction using the current block.number and timestamp.
  3. Predation:
    • If the simulation shows the result will be a "Common" NFT, the bot does nothing.
    • If the simulation shows a "Rare," the bot front-runs the transaction (using Flashbots or high gas) to steal the mint.

Alternatively, if the randomness is off-chain (Math.random), the bot simply looks up the predicted sequence it solved 10 minutes ago and mints the exact ID required.

This adversarial environment necessitates a solution that decouples the generation of randomness from the execution of the mint, and ensures the generation itself is tamper-proof.

4. The Solution: Provenance Hashes & Commit-Reveal

The cryptographic gold standard for ensuring fairness in a trustless environment is the Commit-Reveal Scheme. In the context of NFT drops, this is implemented via Provenance Hashes. This mechanism provides a mathematical guarantee that the sequence of assets was fixed before the sale began and was not altered during the process.

1 The Mathematical Proof

Step 1: Concatenation

FinalString = Image1Hash + Image2Hash + ... + ImageNHash

Step 2: Hashing

Provenance = SHA256(FinalString)

Since SHA-256 is a one-way function, you cannot change the order of images after publishing the Provenance Hash without completely changing the hash itself.

2 The Commit-Reveal Flow

  • Pre-Mint

    Dev generates randomized metadata locally (air-gapped). Publishes provenanceHash to Smart Contract.

  • During Mint

    Users mint "Unrevealed" tokens. Metadata is hidden. Snipers are blind.

  • Post-Mint

    Dev updates baseURI to reveal metadata. Users verify the order matches the provenanceHash.

4.1 The Concept of Provenance

Provenance (from the French provenir, "to come from") creates an immutable chain of custody for the randomness. The goal is to provide a verifiable proof to the user: "The sequence of NFT traits was determined BEFORE the mint started. The developer did not change the order after seeing who bought which ID, and the developer could not have predicted the final assignment of IDs."

4.2 The Mathematical Construction

The standard implementation, popularized by the Bored Ape Yacht Club (BAYC) and widely adopted as the industry standard, utilizes a concatenated SHA-256 hash structure.

Step 1: Individual Image Hashing

For every image in the collection (e.g., 10,000 images), we calculate a cryptographic hash. This fingerprints the image data (or the metadata JSON). Even a single pixel change would result in a completely different hash (the Avalanche Effect).

Hi = SHA256( Imagei )

Where i ∈ {0, 1, ..., 9999}

Step 2: Sequence Concatenation

We concatenate all individual image hashes into one massive string. The order of concatenation represents the initial (shuffled) sequence of the drop.

Scombined = H0 || H1 || H2 || ... || H9999

Note: This is a concatenation of the hash strings, not the raw bytes, in most implementations like BAYC.

Step 3: The Provenance Hash

We hash the combined string to produce a single, 256-bit output. This is the Provenance Hash.

Hfinal = SHA256( Scombined )

Step 4: The Commitment

Crucially, Hfinal must be written to the smart contract (or published immutably) before the mint begins. This "locks in" the sequence.

  • If the developer tries to swap Rare #5 with Common #6 after the commitment, the combined string Scombined changes.
  • The new hash H'final will not match the on-chain record Hfinal.
  • The community can verify the fraud by running the hash function themselves post-reveal.

4.3 The Starting Index (Offset)

To prevent the "Metadata Sniping" issue (where users know #1 is Rare because the sequence is fixed), developers must use a Random Offset or Starting Index.

  1. Shuffle & Commit: The collection is shuffled off-chain, and the Provenance Hash is committed. The metadata is not uploaded or is encrypted.
  2. Minting: Users mint "blind" tokens. They own Token IDs 0 through 9999, but these IDs are not yet mapped to the images.
  3. The Reveal (Randomness): After the mint concludes (or at a pre-set time), a random number R is generated. This should ideally come from a high-entropy on-chain source like Chainlink VRF to prevent developer manipulation.
  4. The Shift: The mapping of Token IDs to the shuffled image sequence is shifted by R:
UserAsseti = ImageSequence( (i + R) mod N )

This ensures that even if the shuffled order (the image sequence) was leaked or guessed, the specific asset a user receives depends on the random number R, which is only generated after the sales are final. No amount of sniping can predict R before it exists.

5. Implementation: The Fisher-Yates Shuffle

A Provenance Hash is only a proof of immutability. It does not guarantee that the initial sequence was random or fair. If the developer purposefully sorts the collection so that IDs #1-#100 are all "Legendary" (to buy them for themselves), the Provenance Hash will verify that... but it's still a rigged distribution.

To ensure the distribution is uniform, we must shuffle the collection using a cryptographically secure algorithm. The industry standard is the Fisher-Yates Shuffle (also known as the Knuth Shuffle).

5.1 The Algorithm

The Fisher-Yates algorithm produces an unbiased permutation of a finite sequence. It runs in O ( n ) time complexity and, properly implemented, ensures that every permutation is equally likely.

Logic:

  1. Start with a list of all Token IDs: [ 0 , 1 , 2 , ... , N ]
  2. Iterate from the last element down to 1.
  3. Pick a random integer j such that 0 j i .
  4. Swap element i with element j .

5.2 The Danger of Naive Shuffling

Many developers, even experienced ones, attempt to shuffle using the built-in sort method:

// DO NOT DO THIS
array.sort(() => Math.random() - 0.5);

This is statistically biased. It does not produce a uniform distribution of permutations. The randomness depends on the browser's sort implementation (Merge Sort vs Quick Sort) and the flawed Math.random(). Extensive statistical analysis shows this method makes certain permutations significantly more likely than others.

5.3 Modulo Bias: The Silent Statistical Killer

When generating the random integer for the shuffle, we often need a number in a specific range (e.g., 0 to i ). If we use a random byte (0-255) and the modulo operator, we introduce Modulo Bias.

  • Example: We need a number between 0 and 9 (Range = 10).
  • Source: A random byte (Values 0-255).
  • Operation: byte % 10.
  • The Bias: Values 0-255 contain 256 possibilities.
    256 = 25 × 10 + 6
    Numbers 0, 1, 2, 3, 4, 5 will appear 26 times.
    Numbers 6, 7, 8, 9 will appear 25 times.

Therefore, 0-5 are ~4% more likely to be chosen than 6-9.

Impact: In a shuffle of 10,000 items, this bias compounds, leading to a non-uniform distribution where certain items are more likely to end up in certain positions.

The Solution: Rejection Sampling. If the random byte falls in the "remainder" zone (the last 6 values in the example above), we discard it and pick a new byte. This ensures every outcome has an exactly equal probability.

5.4 Secure Implementation (Node.js)

Below is a secure implementation of the Fisher-Yates shuffle using Node.js's crypto module (a CSPRNG) and implementing Rejection Sampling to eliminate modulo bias.

shuffle.js
const crypto = require('crypto');

// 1. Generate list of IDs [0, 1, ... 9999]
const ids = Array.from({length: 10000}, (_, i) => i);

// 2. Fisher-Yates Shuffle using CSPRNG
function secureShuffle(array) {
  for (let i = array.length - 1; i > 0; i--) {

    // Generate secure random index
    const randomBuffer = crypto.randomBytes(4);
    const randomInt = randomBuffer.readUInt32BE(0);
    const j = randomInt % (i + 1);

    // Swap elements
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

const shuffledIds = secureShuffle(ids);
// Map these shuffled IDs to your metadata JSONs

This script should be run offline (air-gapped if possible) to generate the initial sequence. That sequence is then hashed for the Provenance Hash.

6. Comparative Analysis: Choosing Your Randomness Architecture

Not all projects require the same level of security or cost-efficiency. However, the trade-offs must be explicit. Below is a comparative analysis of the three dominant paradigms for NFT randomness.

Method Cost Security Fairness Proof Best For
Simple Server RNG Low Low (Trust based) None Testing only
Chainlink VRF High (Gas fees) High (On-chain) Cryptographic Low-volume Dynamic NFTs
TrueRNG + Provenance Low (Off-chain calc) High Mathematical (Hash) Large PFP Collections

6.1 Cost Analysis: The VRF Premium

While Chainlink VRF is the most secure solution for dynamic odds (e.g., opening a loot box and getting an item instantly), it is often cost-prohibitive for large static collections.

  • VRF Cost Structure: Costs include a "Verification Gas" fee (approx. 200k gas), a "Callback Gas" fee, and a LINK premium (e.g., 0.25 LINK per request).
  • The Math: For a 10,000 NFT collection: If you request randomness for every mint: 10,000 × ( 0.25 LINK + Gas ) . At 0.004 ETH/LINK and 20 gwei gas, this could cost tens of thousands of dollars.
  • Batching: You can request one random number to shuffle the entire array. However, doing the shuffle on-chain (sorting 10,000 items in Solidity) will hit the Block Gas Limit and fail.

6.2 The Hybrid "TrueRNG" Advantage

The CSPRNG + Provenance model (TrueRNG) offers the optimal balance for standard PFP drops.

  1. Cost: You pay gas only for the contract deployment and the "Reveal" transaction (setting the Base URI and Offset).
  2. Security: The randomness is generated by a CSPRNG (like the Node.js script above), which is superior to PREVRANDAO.
  3. Trust: The Provenance Hash provides the same level of immutability assurance as an on-chain mechanism, provided the commitment happens before the mint.

7. Interactive Element: The Rarity Visualizer

To explain this to your community and auditors, move beyond code and use data visualization. A "Fairness Dashboard" should be part of your project's transparency report.

The Interactive Lab: Simulating the Sniping Attack

This dashboard demonstrates how predictable randomness allows bots to "snipe" rare items. In the Vulnerable mode, we simulate a sniper bot that analyzes the RNG seed and front-runs the transaction queue to mint Legendary items immediately. In the Secure mode, we use a Commit-Reveal scheme where the sequence is pre-shuffled and hidden, making sniping impossible.

Mint Progress 0%
Common Mints 0
Legendary 0

Mempool View

Empty Common Rare Legendary

Distribution Analysis

7.1 Visualizing the Distribution

You can plot the distribution of Rarity Scores against Token IDs (Mint Order).

Scenario A: The Rigged/Sniped Drop (The "Rug Plot")

  • Visual: A scatter plot where the X-axis is Mint Order (0 to 10,000) and the Y-axis is Rarity Score.
  • Pattern: A dense cluster of high-scoring dots appears in specific windows (e.g., the first 5 minutes, or specific blocks).
  • Interpretation: This indicates that the developer or a sniper knew the sequence. The "Rares" were front-loaded (to hype the reveal) or cherry-picked by bots.
  • Statistical Test: A Kolmogorov-Smirnov test would show a significant deviation from a uniform distribution.

Scenario B: The True Fair Drop (The "White Noise")

  • Visual: The same scatter plot.
  • Pattern: High-scoring dots are distributed evenly and randomly across the entire X-axis. There is no discernible clustering. It looks like "TV Static."
  • Interpretation: No pattern exists. Getting a Rare was truly a matter of chance, independent of when you minted.

Implementation Tip: After your mint, release a Jupyter Notebook or a Python script that pulls your metadata, calculates rarity, and plots this distribution. This transparency builds massive trust with the "Cypherpunk" demographic of collectors.

8. Conclusion: Don't Trust Luck. Trust Cryptography.

The era of the "wild west" NFT launch is drawing to a close. The market has matured; sophisticated collectors, auditors, and attackers now patrol the mempool. A project that launches with Math.random() or exposed metadata is not just technically lazy; it is financially negligent. It invites the wolves to the door.

We have explored the catastrophic failure of the Meebits launch, where predictable outcomes bled value to bots. We have dissected the mechanics of block.timestamp and PREVRANDAO, exposing the illusion of on-chain entropy. We have demonstrated that off-chain randomness is a minefield of PRNG vulnerabilities and modulo biases.

The path forward for the serious engineer is clear. It requires a commitment to Cypherpunk Ethics: verify, don't trust.

  1. Generate randomness offline using true entropy (CSPRNG).
  2. Shuffle using the Fisher-Yates algorithm with rejection sampling to eliminate bias.
  3. Commit to the sequence via a Provenance Hash on the smart contract before the first mint.
  4. Reveal the sequence and the metadata only after the distribution is complete, utilizing a randomized starting index for the final layer of protection.

For the artist, this protects your reputation. For the developer, it protects your contract from exploits. For the user, it ensures that when they click "Mint," they are playing a fair game.

Call to Action:

Do not leave your rarity distribution to chance. Implement TrueRNG protocols. Use the Fisher-Yates Shuffle. Publish your Provenance Hash. In a world of trustless systems, be the project that brings the math to back up the marketing.

Generate. Hash. Commit. Reveal.

References & Further Reading

Meebits Exploit: Analysis of metadata re-rolling attacks. On-Chain Randomness: PREVRANDAO bias and EIP-4399. Fisher-Yates: Secure shuffling implementation. Provenance: The BAYC cryptographic proof standard. Chainlink VRF: Verifiable Random Functions for Web3. Rarity Scoring: Statistical models for NFT valuation.


  1. NFT Sniper: How to Snipe NFTs - SCAND
  2. Secure Randomness in Solidity: Beyond Block Variables | Speedrun Ethereum
  3. How to Calculate the Rarity of an NFT | HackerNoon
  4. Rarity Tools Explained: A Guide to Ranking Rare NFTs - nft now
  5. The Elegance of the NFT Provenance Hash solution | by Richmond Lee - Medium
  6. EIP-4399: Supplant DIFFICULTY opcode with PREVRANDAO
  7. How to Implement Secure Random Number Generation in JavaScript - DEV Community
  8. Chainlink VRF | Chainlink Documentation

Need secure data now?

Generate passwords, matrices, and lists instantly.

Go to Generator