The OneShot::mintRapper()
function presents a reentrancy vulnerability due to its non-compliance with the Checks-Effects-Interactions (CEI) pattern. This flaw allows attackers to exploit the system by creating a contract specifically for minting new rappers. Attackers can then engage and win in battles against defenders with skill points under 65.
The issue stems from the OneShot::mintRapper()
function executing safeMint()
prior to updating the RapperStats
, violating the CEI pattern. This order of operations allows for the minting of a rapper without proper initialization of their statistics:
However, due to improper initialization, the newly minted rapper's stats default to zero values, inadvertently assigning them 65 skill points:
The resulting RapperStats
of the tokenId we are minting will be RapperStats({ weakKnees: false, heavyArms: false, spaghettiSweater: false, calmAndReady: false, battlesWon: 0 })
, giving us 65 points.
An attacker can deploy a contract that implements the onERC721Received()
function, which is invoked by _safeMint()
to ensure the recipient can accept ERC721 tokens. This contract can then initiate RapBattle::goOnStageOrBattle()
against a defender with less than 65 skill points, leveraging the flawed stat assignment for an unfair advantage.
This vulnerability allows an attacker to mint a rapper with artificially high skill points (equivalent to a 3-day stake) and exploit this to win battles against less skilled defenders.
Manual review.
To mitigate this vulnerability, the order of operations in OneShot::mintRapper()
should be adjusted to adhere to the CEI pattern, ensuring proper initialization of rapper stats before the minting process:
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.