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

Code before:
        randoms = _newRandoms;
    }

    modifier restricted() {
        require(hasRole(GAME_ADMIN, msg.sender), "Missing GAME_ADMIN role");
        _;
    }

    modifier oncePerBlock(address user) {
        require(lastBlockNumberCalled[user] < block.number, "Only callable once per block");
        lastBlockNumberCalled[user] = block.number;
        _;
    }

    modifier isWeaponOwner(uint256 weapon) {
        require(weapons.ownerOf(weapon) == msg.sender, "Not the weapon owner");
        _;
    }

    modifier isCharacterOwner(uint256 character) {
        require(characters.ownerOf(character) == msg.sender, "Not the character owner");
        _;
    }

    modifier doesNotHaveMoreThanMaxCharacters() {
        require(characters.balanceOf(msg.sender) <= characters.characterLimit, "Too many characters owned");
        _;
    }

    modifier isTargetValid(uint256 character, uint256 weapon, uint32 target) {
        bool foundMatch = false;
        uint32[4] memory targets = getTargets(character, weapon);
        for(uint i = 0; i < targets.length; i++) {
            if(targets[i] == target) {
                foundMatch = true;
            }
        }
        require(foundMatch, "Target invalid");
        _;
    }

    modifier requestPayFromPlayer(int128 usdAmount) {
        uint256 skillAmount = usdToSkill(usdAmount);

        (,, uint256 fromUserWallet) =
            getSkillToSubtract(
                inGameOnlyFunds[msg.sender],
                tokenRewards[msg.sender],
                skillAmount
            );


Review comment (suggestion):
I believe state variables of other contracts cannot be accessed like this. They need to be treated like getter functions. Also requires the state variable in question to be `public`.

```suggestion
        require(characters.balanceOf(msg.sender) <= characters.characterLimit(), "Too many characters owned");
```

Code after:

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

    function reforgeWeapon(uint256 reforgeID, uint256 burnID) public
            doesNotHaveMoreThanMaxCharacters
            isWeaponOwner(reforgeID) isWeaponOwner(burnID) requestPayFromPlayer(reforgeWeaponFee) {
        _payContract(msg.sender, reforgeWeaponFee);
        weapons.reforge(reforgeID, burnID);
    }

    function migrateRandoms(IRandoms _newRandoms) external {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Not admin");
        randoms = _newRandoms;
    }

    modifier onlyNonContract() {
        require(tx.origin == msg.sender, "Only EOA allowed (temporary)");
        _;
    }

    modifier restricted() {
        require(hasRole(GAME_ADMIN, msg.sender), "Missing GAME_ADMIN role");
        _;
    }

    modifier oncePerBlock(address user) {
        require(lastBlockNumberCalled[user] < block.number, "Only callable once per block");
        lastBlockNumberCalled[user] = block.number;
        _;
    }

    modifier isWeaponOwner(uint256 weapon) {
        require(weapons.ownerOf(weapon) == msg.sender, "Not the weapon owner");
        _;
    }

    modifier isCharacterOwner(uint256 character) {
        require(characters.ownerOf(character) == msg.sender, "Not the character owner");
        _;
    }

    modifier doesNotHaveMoreThanMaxCharacters() {
        require(characters.balanceOf(msg.sender) <= characters.characterLimit(), "Too many characters owned");
        _;
    }

    modifier isTargetValid(uint256 character, uint256 weapon, uint32 target) {
        bool foundMatch = false;
        uint32[4] memory targets = getTargets(character, weapon);