[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.