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

Code before:

    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) internal pure returns (uint256 seed) {
        seed = RandomUtil.combineSeeds(seedId, uint(1));
    }

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

    function generateSeed() public {
        require(itemFlatPrices[ITEM_SHIELD] > 0);
        payCurrency(msg.sender, itemFlatPrices[ITEM_SHIELD], CURRENCY_SKILL);
        SafeRandoms(links[LINK_SAFE_RANDOMS]).requestSingleSeed(tx.origin, getSeed(uint(SHIELD_SEED)));
    }

    function purchaseShield() public {
        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)), true, false);
        shields.mint(msg.sender, shieldType, seed);
    }

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

    modifier onlyGame() {
        require(hasRole(GAME, msg.sender), "Only game");
        _;
    }

    modifier isAdmin() {
         _isAdmin();
        _;

Review comment (suggestion):
Worth mentioning that if we ever sell other items using safe randoms through blacksmith, the abi will have to change for these seed related functions, and need to be updated in frontend even for shields. Not a requirement at this time, but it's worth knowing we'll probably take an item ID and/or type, maybe amount as a param(s) for the purchase and claim.

Code after:

    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 ========== */

    modifier onlyGame() {
        require(hasRole(GAME, msg.sender), "Only game");
        _;