- Type: Exploit
- Network: Ethereum
- Total lost: 400 NFTs were claimed
- Category: Data validation
- Exploited contracts:
- Attack transactions:
- Attack Block:: 15460094
- Date: Sept 02, 2022
- Reproduce:
forge test --match-contract Exploit_Bad_Guys_NFT -vvv
- Get whitelisted
- Call the whitelist mint function with a high number of
chosenAmount
so you mint all available NFTs.
The attacker claimed 400 NFTs in a single transaction. The mistake is in the WhiteListMint
function, where anyone whitelisted can pass an arbitrary chosenAmount
. The _numberMinted_
map is only updated after calling the function, so the require
passes for any number on the first try.
function WhiteListMint(bytes32[] calldata _merkleProof, uint256 chosenAmount)
public
{
require(_numberMinted(msg.sender)<1, "Already Claimed");
require(isPaused == false, "turn on minting");
require(
chosenAmount > 0,
"Number Of Tokens Can Not Be Less Than Or Equal To 0"
);
require(
totalSupply() + chosenAmount <= maxsupply - reserve,
"all tokens have been minted"
);
bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
require(
MerkleProof.verify(_merkleProof, rootHash, leaf),
"Invalid Proof"
);
_safeMint(msg.sender, chosenAmount);
}
- The
chosenAmount
parameter seems to be useless and would better be a constant of1
if that was the intended usage. - Otherwise, if it was intended to allow for more than one mint per accoutn, restrict the
chosenAmount
parameter.