[H4] - Attacker can use Reentrancy to go to battle with good stats without improving his skill by staking
The function OneShot.mintRapper() is subject to read-only reentrancy. A user could mint the NFT, go directly to battle with good stats without staking in the minting process.
An attacker could create a Smart Contract and implement the function function onERC721Received(address, address, uint256 id, bytes calldata) with the call of rapBattleContract.goOnStageOrBattle.
When the Attacker Smart Contract mint a OneShot NFT by calling OneShotNFT.mintRapper(), the Contract receive the NFT and automatically trigger onERC721Received function in the Attacker smart contract where he implement something to call rapBattleContract.goOnStageOrBattle.
Stats rapperStats[tokenId] is not initialized yet because the stats are updated after safeMint() in the OneShot.mintRapper() function.
The Attacker use reentrancy to benefit from better stats without stakeing to improve his skill.
If a user already has cred token in the Attacker smart contract and goes to battle before his stats are updated, he would have a better start because rapperStats.weakKnees, rapperStats.weakKnees, rapperStats.weakKnees are not initialized yet and will equal to false.
0 - User mints OneShot NFT
1 - User and user2 already have 3 cred tokens
2 - User goes to battle with his NFT as defender
3 - User2 calls the function attack() of the AttackerContract smart contract to mint NFT
4 - User3 receives the NFT in the Smart Contract that triggers the function function onERC721Received, that makes him go on Battle as challenger with good stats (not initialized yet)
To run the exploit, add this function in the file OneShotTest.t.sol:
Foundry & slither
In the function mintRapper() of Smart Contract OneShot.sol, update the stats before minting the NFT:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.