Skip to content

Weak On-Chain Randomness

SAFE-0126 Randomness Checked automatically by the scanner
1

What goes wrong

Randomness is derived from on-chain values an attacker can see or influence — block.timestamp, blockhash, block.prevrandao, or block.difficulty. A contract (or a validator) can compute the same value in the same block and only participate when it wins, breaking any lottery/NFT-mint fairness.

2

The vulnerable pattern

proof of concept — how it is exploited
// uint r = uint(keccak256(abi.encodePacked(block.timestamp, blockhash(block.number-1))));
// attacker contract computes the same r in the same block and calls
// play() only when r maps to a win -> guaranteed jackpot.
3

How to fix it

the pattern that is safe
// use a verifiable randomness source (Chainlink VRF)
function fulfillRandomWords(uint256, uint256[] memory words) internal override {
    winner = players[words[0] % players.length];
}
On-chain data is not random; use Chainlink VRF.
Check your own contract for this

The SaferICO scanner runs 201 detectors over your Solidity source, SAFE-0126 among them. Paste an address or the source itself — a small per-scan fee, shown before you sign, or unlimited on any plan.

Run the scanner See how it is attacked Read the docs