Repository: CryptoBlades/cryptoblades
File: contracts/Blacksmith.sol (Solidity)

Code before:
        itemFlatPrices[ITEM_CHARACTER_TRAITCHANGE_EARTH] = 0.2 ether;
        itemFlatPrices[ITEM_CHARACTER_TRAITCHANGE_WATER] = 0.2 ether;
        itemFlatPrices[ITEM_CHARACTER_TRAITCHANGE_LIGHTNING] = 0.2 ether;
    }

    function migrateTo_bcdf4c(CBKLandSale _cbkLandSale) external {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Not admin");

        cbkLandSale = _cbkLandSale;
    }

    /* ========== VIEWS ========== */

    /* ========== MUTATIVE FUNCTIONS ========== */

    function recoverToken(address tokenAddress, uint256 amount) public {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Not admin");

        IERC20(tokenAddress).safeTransfer(msg.sender, amount);
    }

    function setSafeRandoms(SafeRandoms _safeRandoms) public isAdmin {
        safeRandoms = _safeRandoms;
    }

    function hasSeed() public view returns (bool) {
        return safeRandoms.hasSingleSeedRequest(tx.origin, getSeed());
    }

    function generateSeed() public {
        safeRandoms.requestSingleSeed(tx.origin, getSeed());
    }

    function getSeed() internal pure returns (uint256 seed) {
        seed = RandomUtil.combineSeeds(uint(SHIELD_SEED), uint(1));
    }

    function purchaseShield() public {
        require(itemFlatPrices[ITEM_SHIELD] > 0);
        uint256 seed = safeRandoms.popSingleSeed(msg.sender, getSeed(), true, true);
        uint256 shieldType = numberParameters[VAR_PURCHASE_SHIELD_TYPE];
        if(shieldType != 0) {
            require(numberParameters[VAR_PURCHASE_SHIELD_SUPPLY] > 0);
            numberParameters[VAR_PURCHASE_SHIELD_SUPPLY] -= 1;
        }
        payCurrency(msg.sender, itemFlatPrices[ITEM_SHIELD], CURRENCY_SKILL);
        shields.mint(msg.sender, shieldType, seed);
    }

    /* ========== MODIFIERS ========== */


Review comment (suggestion):
May be forward thinking to have a seed ID param on this function for frontend compatibility. Assuming we'll sell more seed-bound things in blacksmith in the future, so the ABI doesnt have to change. The frontend would have to know about the seed id constant though.

Code after:
        itemFlatPrices[ITEM_CHARACTER_TRAITCHANGE_EARTH] = 0.2 ether;
        itemFlatPrices[ITEM_CHARACTER_TRAITCHANGE_WATER] = 0.2 ether;
        itemFlatPrices[ITEM_CHARACTER_TRAITCHANGE_LIGHTNING] = 0.2 ether;
    }

    function migrateTo_bcdf4c(CBKLandSale _cbkLandSale) external {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Not admin");

        cbkLandSale = _cbkLandSale;
    }

    /* ========== VIEWS ========== */

    /* ========== MUTATIVE FUNCTIONS ========== */

    function recoverToken(address tokenAddress, uint256 amount) public {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Not admin");

        IERC20(tokenAddress).safeTransfer(msg.sender, amount);
    }

    function getSeed(uint seedId, uint shieldType) internal pure returns (uint256 seed) {
        uint[] memory seeds = new uint[](3);
        seeds[0] = seedId;
        seeds[1] = uint(1);
        seeds[2] = shieldType;
        seed = RandomUtil.combineSeeds(seeds);
    }

    function hasSeed(uint seedId, uint shieldType) public view returns (bool) {
        return SafeRandoms(links[LINK_SAFE_RANDOMS]).hasSingleSeedRequest(msg.sender, getSeed(seedId, shieldType));
    }

    function generateShieldSeed() external {
        require(itemFlatPrices[ITEM_SHIELD] > 0);
        uint256 shieldType = numberParameters[VAR_PURCHASE_SHIELD_TYPE];
        payCurrency(msg.sender, itemFlatPrices[ITEM_SHIELD], CURRENCY_SKILL);
        SafeRandoms(links[LINK_SAFE_RANDOMS]).requestSingleSeed(msg.sender, getSeed(uint(SHIELD_SEED), shieldType));
    }

    function claimShield() external {
        uint256 shieldType = numberParameters[VAR_PURCHASE_SHIELD_TYPE];
        if(shieldType != 0) {
            require(numberParameters[VAR_PURCHASE_SHIELD_SUPPLY] > 0);
            numberParameters[VAR_PURCHASE_SHIELD_SUPPLY] -= 1;
        }
        uint256 seed = SafeRandoms(links[LINK_SAFE_RANDOMS]).popSingleSeed(msg.sender, getSeed(uint(SHIELD_SEED), shieldType), true, false);
        shields.mint(msg.sender, shieldType, seed);
    }

    /* ========== MODIFIERS ========== */