The mintSnowman
function can be called by anyone in order to mint any number of Snowman NFTs without having any Snow token balance. This is possible due to the mintSnowman
function missing access controls on who can execute.
The Protocol has the invariant "By staking Snow tokens, users receive Snowman NFTs proportional to their Snow token holdings." However, the current implementation logic does not enforce this statement. The Snowman::mintSnowman
function can be called directly by anyone who does not have any Snow tokens allowing them to freely mint any number of Snowman NFTs without a prior investment into the protocol.
This is possible due to missing access controls on the mintSnowman
function - mainly onlyOwner
. This function is supposed to only be invoked via the SnowmanAirdrop:claimSnowman
function after the user has transferred their Snow tokens into the SnowmanAirdrop
contract. Therefore the Snowman
contract is expected to be owned by SnowmanAirdrop
but is currently not.
Vulnerable Code
The related vulnerable function is described below:
The severity of this issue can be classified as High for the following reasons:
Impact: High - There is broken core invariant - users must exchange snow tokens for NFTs. This invariant is also the expected source of profit for the protocol meaning the Protocol will loose funds/profits from sales of Snow tokens.
Likelihood: High - the likelihood of exploitation is high due to the attack path being straightforward and no prior requirements.
As proof of the validity of this issue, I have provided a runnable PoC.
Description
The script shows the attacker - Bob - holds 0 snow tokens.
The mintSnowman
is invoked by Bob to create 10 Snowman NFTs.
The script confirms that Bob holds and owns all 10 minted Snowman NFTs.
Code
Run with: forge test --mt testUnauthorizedMintingOfSnowmanNFTs -vvv
The recommended mitigation for this unauthorized NFT minting is to implement Access controls into the Snowman
contract ensuring only SnowmanAirdrop
can call mintSnowman
.
The protocol logic requires that in order to mint an NFT , a user must hold Snow tokens and these are exchanged for the Snowman NFT. The transfer logic and checks are contained in the SnowmanAirdrop
contract. Therefore, the owner of Snowman
should be SnowmanAirdrop
. This can be implemented directly in the constructor.
Furthermore, the mintSnowman
function should have the onlyOwner
modifier.
The mint function of the Snowman contract is unprotected. Hence, anyone can call it and mint NFTs without necessarily partaking in the airdrop.
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.