skills/vulnerability-patterns/weak-sources-randomness/SKILL.md
- Contract generates "random" values using on-chain data: `block.timestamp`, `blockhash`, `block.difficulty` / `block.prevrandao`, `block.number`, or combinations thereof
npx skillsauth add apegurus/solidity-argus weak-sources-randomnessInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
block.timestamp, blockhash, block.difficulty / block.prevrandao, block.number, or combinations thereoffunction drawLottery() external {
// All inputs are deterministic and publicly visible
// Another contract can compute the same value in the same tx
uint256 random = uint256(keccak256(abi.encodePacked(
block.timestamp,
block.prevrandao,
msg.sender
))) % 100;
if (random < 5) {
_payWinner(msg.sender);
}
}
// Attacker contract
contract Exploit {
function attack(Lottery target) external {
// Compute the same "random" value before calling
uint256 random = uint256(keccak256(abi.encodePacked(
block.timestamp,
block.prevrandao,
address(this)
))) % 100;
// Only call if we'll win
if (random < 5) {
target.drawLottery();
}
}
}
block.timestamp, block.prevrandao, block.difficulty, blockhash, block.number used as inputs to keccak256 or arithmetic operations producing a "random" valueblockhash is used for a future block (returns 0 for blocks not yet mined) or a block older than 256 blocks (also returns 0)block.prevrandao on PoS Ethereum provides sufficient entropy for the specific use case (not for high-value outcomes)block.timestamp, blockhash, or block.prevrandao alone for randomness in high-value contextsimport {VRFConsumerBaseV2} from "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";
contract FairLottery is VRFConsumerBaseV2 {
function requestRandom() external {
requestRandomWords(keyHash, subId, confirmations, gasLimit, 1);
}
function fulfillRandomWords(uint256, uint256[] memory randomWords) internal override {
uint256 winner = randomWords[0] % participants.length;
_payWinner(participants[winner]);
}
}
testing
Specialist profile for mechanically applying the attack-vector deck and classifying vectors as skip, drop, or investigate.
tools
Specialist profile for libraries, helpers, base contracts, adapters, encoders, wrappers, and integration glue.
testing
Specialist profile for rounding, scale, decimal, downcast, and arithmetic accounting edge cases.
testing
Specialist profile for extracting conservation laws and state couplings, then searching for violating paths.