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

Code before:
        uint256 convertedAmount = usdToSkill(getMintCharacterFee());
        _payContractTokenOnly(msg.sender, convertedAmount);

        uint256 seed = randoms.getRandomSeed(msg.sender);
        characters.mint(msg.sender, seed);

        // first weapon free with a character mint, max 1 star
        if(weapons.balanceOf(msg.sender) == 0) {
            weapons.mintWeaponWithStars(msg.sender, 0, uint256(keccak256(abi.encodePacked(blockhash(block.number - 1), msg.sender))), 100);
        }

        _updateCharacterMintFee();
    }

    function generateWeaponSeed(uint32 num, uint8 chosenElement) external onlyNonContract oncePerBlock(msg.sender) {
        uint8 chosenElementFee = chosenElement == 100 ? 1 : 2;
        int128 mintWeaponFee =
            getMintWeaponFee()
                .mul(ABDKMath64x64.fromUInt(num))
                .mul(ABDKMath64x64.fromUInt(chosenElementFee));
        _payContractConvertedSupportingStaked(msg.sender, usdToSkill(mintWeaponFee));
        _updateWeaponMintFee(num);
        SafeRandoms(links[LINK_SAFE_RANDOMS]).requestSingleSeed(tx.origin, getSeed(uint(WEAPON_SEED), num, chosenElement));
    }

    function generateWeaponSeedUsingStakedSkill(uint32 num, uint8 chosenElement) external onlyNonContract oncePerBlock(msg.sender) {
        uint8 chosenElementFee = chosenElement == 100 ? 1 : 2;
        int128 discountedMintWeaponFee =
            getMintWeaponFee()
                .mul(PAYMENT_USING_STAKED_SKILL_COST_AFTER_DISCOUNT)
                .mul(ABDKMath64x64.fromUInt(num))
                .mul(ABDKMath64x64.fromUInt(chosenElementFee));
        _payContractStakedOnly(msg.sender, usdToSkill(discountedMintWeaponFee));
        _updateWeaponMintFee(num);
        SafeRandoms(links[LINK_SAFE_RANDOMS]).requestSingleSeed(tx.origin, getSeed(uint(WEAPON_SEED), num, chosenElement));
    }

    function mintWeapon(uint32 quantity, uint8 chosenElement, uint256 eventId) external onlyNonContract oncePerBlock(msg.sender) {
        require(quantity > 0 && quantity <= 10);
        if(eventId > 0) {
            specialWeaponsManager.addShards(msg.sender, eventId, quantity);
        }
        uint256 seed = SafeRandoms(links[LINK_SAFE_RANDOMS]).popSingleSeed(msg.sender, getSeed(uint(WEAPON_SEED), quantity, chosenElement), true, false);
        weapons.mintN(msg.sender, quantity, seed, chosenElement);
    }

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

    function getSeed(uint seedId, uint quantity, uint element) internal pure returns (uint256 seed) {

Review comment (suggestion):
We should `require(num > 0 && num <= 10)`. If they input anything > 10 they won't be able to mint anything from this seed.

Code after:

        uint256 convertedAmount = usdToSkill(getMintCharacterFee());
        _payContractTokenOnly(msg.sender, convertedAmount);

        uint256 seed = randoms.getRandomSeed(msg.sender);
        characters.mint(msg.sender, seed);

        // first weapon free with a character mint, max 1 star
        if(weapons.balanceOf(msg.sender) == 0) {
            weapons.mintWeaponWithStars(msg.sender, 0, uint256(keccak256(abi.encodePacked(blockhash(block.number - 1), msg.sender))), 100);
        }

        _updateCharacterMintFee();
    }

    function generateWeaponSeed(uint32 quantity, uint8 chosenElement, uint256 eventId) external onlyNonContract oncePerBlock(msg.sender) {
        require(quantity > 0 && quantity <= 10);
        require(userVars[msg.sender][USERVAR_CLAIM_WEAPON_DATA] == 0);
        uint8 chosenElementFee = chosenElement == 100 ? 1 : 2;
        int128 mintWeaponFee =
            getMintWeaponFee()
                .mul(ABDKMath64x64.fromUInt(quantity))
                .mul(ABDKMath64x64.fromUInt(chosenElementFee));
        _payContractConvertedSupportingStaked(msg.sender, usdToSkill(mintWeaponFee));
        _updateWeaponMintFee(quantity);
        if (eventId > 0) {
            specialWeaponsManager.addShards(msg.sender, eventId, quantity);
        }
        SafeRandoms(links[LINK_SAFE_RANDOMS]).requestSingleSeed(msg.sender, getSeed(uint(WEAPON_SEED), quantity, chosenElement));
        userVars[msg.sender][USERVAR_CLAIM_WEAPON_DATA] = uint256(uint256(chosenElement) | (uint256(quantity) << 32));
    }

    function generateWeaponSeedUsingStakedSkill(uint32 quantity, uint8 chosenElement, uint256 eventId) external onlyNonContract oncePerBlock(msg.sender) {
        require(quantity > 0 && quantity <= 10);
        require(userVars[msg.sender][USERVAR_CLAIM_WEAPON_DATA] == 0);
        uint8 chosenElementFee = chosenElement == 100 ? 1 : 2;
        int128 discountedMintWeaponFee =
            getMintWeaponFee()
                .mul(PAYMENT_USING_STAKED_SKILL_COST_AFTER_DISCOUNT)
                .mul(ABDKMath64x64.fromUInt(quantity))
                .mul(ABDKMath64x64.fromUInt(chosenElementFee));
        _payContractStakedOnly(msg.sender, usdToSkill(discountedMintWeaponFee));
        _updateWeaponMintFee(quantity);
        if (eventId > 0) {
            specialWeaponsManager.addShards(msg.sender, eventId, quantity);
        }
        SafeRandoms(links[LINK_SAFE_RANDOMS]).requestSingleSeed(msg.sender, getSeed(uint(WEAPON_SEED), quantity, chosenElement));
        userVars[msg.sender][USERVAR_CLAIM_WEAPON_DATA] = uint256(uint256(chosenElement) | (uint256(quantity) << 32));
    }

    function mintWeapon() external onlyNonContract oncePerBlock(msg.sender) {