# DeFiHackLab Group1 HW5 團體作業 組別參與者:Mussina, Rock, ichi, D13, Jeff ## Vulnerabilities ### battle 之前可以先知道 defender token ID, 就可以先知道對方分數。 - D13 ### Conquest.sol , function _battle() , random 可以被預測。 - ichi ### 不需要有 NFT & token 也可以當 challenger, 隨便玩、沒成本。 - Rock ### weedingOrBattle() 可以 bet 0 - Mussina --- # defender 數值可以查詢 ## Location - https://github.com/DeFiHackLabs-BootCamp/Fall-HW5-Team/blob/436857993243911aea3589102c735a6445bd78be/src/Conquest.sol#L44 - https://github.com/DeFiHackLabs-BootCamp/Fall-HW5-Team/blob/436857993243911aea3589102c735a6445bd78be/src/Conquest.sol#L86 ## Description ```solidity function weedingOrBattle(uint256 _tokenId, uint256 _compensationBet) external { if (defender == address(0)) { defender = msg.sender; defenderBet = _compensationBet; defenderTokenId = _tokenId; emit Weeding(msg.sender, _tokenId, _compensationBet); requestQuestNft.transferFrom(msg.sender, address(this), _tokenId); CompensationToken.transferFrom(msg.sender, address(this), _compensationBet); } else { // CompensationToken.transferFrom(msg.sender, address(this), _compensationBet); _battle(_tokenId, _compensationBet); } } ``` 在 `weedingOrBattle` 中,會將先申請的人設定為防禦者,並以 event 的方式紀錄 defender 的地址與 tokenId,再透過以下 function 取得該 token 的數值 ```solidity function getChiikawaSkill(uint256 _tokenId) public view returns (uint256 finalSkill) { IRequestQuest.ChiikawaStats memory stats = requestQuestNft.getChiikawaStats(_tokenId); finalSkill = BASE_SKILL; if (stats.smallFeet) { finalSkill -= VICE_DECREMENT; } if (stats.weapon) { finalSkill -= VICE_DECREMENT; } if (stats.miniBag) { finalSkill -= VICE_DECREMENT; } if (stats.calmAndReady) { finalSkill += VIRTUE_INCREMENT; } } ``` ## Recommendation 1. 透過加密的方式儲存 Chiikawa 的數據 2. 設定 function `getChiikawaSkill()` 的訪問權限,避免其他人可以讀取 --- # User can bet 0 when battle ## Location https://github.com/DeFiHackLabs-BootCamp/Fall-HW5-Team/blob/436857993243911aea3589102c735a6445bd78be/src/Conquest.sol#L38 ```solidity function weedingOrBattle(uint256 _tokenId, uint256 _compensationBet) external { if (defender == address(0)) { ... } else { ... } } ``` User can bet 0 when calling weedingOrBattle(uint256, uint256) function by setting _compensationBet equals 0. Not a big issue or vulnerability but doesn't make sense. ## Recommendation - set minimum betting amount - check betting amount(_compensationBet) in weedingOrBattle(uint256, uint256) function.