Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: low
Valid

`OneShot.sol` isn't updating the battles won, breaking the protocol functionality

  • Description:

    • After a battle is finished, the winner should receive a status update on battlesWon. However, this never happens.

    • Impact:

      • The bonus over battles won is not applied. Breaking the functionality.

    • Proof of Concept:

      Add the code below to `OneShot.t.sol`
      function testBattleWonNeverUpdated() public mintRapper {
      vm.startPrank(user);
      oneShot.approve(address(rapBattle), 0);
      rapBattle.goOnStageOrBattle(0, 0);
      vm.stopPrank();
      vm.startPrank(challenger);
      oneShot.mintRapper();
      oneShot.approve(address(rapBattle), 1);
      rapBattle.goOnStageOrBattle(1, 0);
      IOneShot.RapperStats memory statsDefender = oneShot.getRapperStats(0);
      IOneShot.RapperStats memory statsChallenger = oneShot.getRapperStats(1);
      console.log(statsDefender.battlesWon);
      console.log(statsChallenger.battlesWon);
      }
    • Recommendation:

      Update the `OneShot.sol::onlyStreetContract` modifier to accept calls from `RapBattle.sol::_battle` and create the helpe function below
      + modifier onlyStreetContract() {
      + require(msg.sender == address(_streetsContract) || msg.sender == address(s_rap), "Not Allowed");
      + _;
      + }
      + import {RapBattle} from "./RapBattle.sol";
      + event OneShot__RapBattleAddressUpdated();
      + function setRapBattleContract(address _rapBattle) external onlyOwner {
      + s_rap = RapBattle(_rapBattle);
      + emit OneShot__RapBattleAddressUpdated();
      + }
      Update the `RapBattle.sol::_battle` as follow
      function _battle(uint256 _tokenId, uint256 _credBet) internal {
      address _defender = defender;
      require(defenderBet == _credBet, "RapBattle: Bet amounts do not match");
      uint256 defenderRapperSkill = getRapperSkill(defenderTokenId);
      uint256 challengerRapperSkill = getRapperSkill(_tokenId);
      uint256 totalBattleSkill = defenderRapperSkill + challengerRapperSkill;
      uint256 totalPrize = defenderBet + _credBet;
      uint256 random =
      uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender))) % totalBattleSkill;
      // Reset the defender
      defender = address(0);
      emit Battle(msg.sender, _tokenId, random < defenderRapperSkill ? _defender : msg.sender);
      // If random <= defenderRapperSkill -> defenderRapperSkill wins, otherwise they lose
      if (random <= defenderRapperSkill) {
      + IOneShot.RapperStats memory stats = oneShotNft.getRapperStats(defenderTokenId);
      + stats.battlesWon++;
      + oneShotNft.updateRapperStats(defenderTokenId, stats.weakKnees, stats.heavyArms, stats.spaghettiSweater, stats.calmAndReady, stats.battlesWon);
      // We give them the money the defender deposited, and the challenger's bet
      credToken.transfer(_defender, defenderBet);
      credToken.transferFrom(msg.sender, _defender, _credBet);
      } else {
      + IOneShot.RapperStats memory stats = oneShotNft.getRapperStats(_tokenId);
      + stats.battlesWon++;
      + oneShotNft.updateRapperStats(_tokenId, stats.weakKnees, stats.heavyArms, stats.spaghettiSweater, stats.calmAndReady, stats.battlesWon);
      // Otherwise, since the challenger never sent us the money, we just give the money in the contract
      credToken.transfer(msg.sender, _credBet);
      }
      totalPrize = 0;
      // Return the defender's NFT
      oneShotNft.transferFrom(address(this), _defender, defenderTokenId);
      }
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

`battlesWon` is never updated

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.