sherlock-audit / 2024-04-titles-judging

6 stars 6 forks source link

ast3ros - Bypass minting fee in mintBatch function #307

Closed sherlock-admin4 closed 2 months ago

sherlock-admin4 commented 3 months ago

ast3ros

high

Bypass minting fee in mintBatch function

Summary

The mintBatch function improperly calculates minting fees, potentially allowing a malicious user to exploit this oversight by batch minting multiple tokens to themselves and paying only the fee for a single token issuance.

Vulnerability Detail

In the mintBatch function, the minting fee is calculated and collected for a single issuance quantity (amount_). However, the function issues the specified amount of tokens to each receiver in the `receiversarray. This discrepancy means that while the fee is only paid once foramounttokens, the function could mintamount * receivers_.length` tokens, effectively allowing users to bypass the correct fee payment by setting multiple receivers, especially if all receivers are the same account.

    function mintBatch(
        address[] calldata receivers_,
        uint256 tokenId_,
        uint256 amount_,
        bytes calldata data_
    ) external payable {
        // wake-disable-next-line reentrancy
        FEE_MANAGER.collectMintFee{value: msg.value}(
            this, tokenId_, amount_, msg.sender, address(0), works[tokenId_].strategy
        );

        for (uint256 i = 0; i < receivers_.length; i++) {
            _issue(receivers_[i], tokenId_, amount_, data_); // @audit fee is calculated for amount_ but issue length * amount_s
        }

        _refundExcess();
    }

https://github.com/sherlock-audit/2024-04-titles/blob/2ac20d07d0b4562c0b0ee15e1becbf786f0ed896/wallflower-contract-v2/src/editions/Edition.sol#L304-L320

Impact

Lead to significant revenue loss as users can mint multiple tokens while evading the intended fee structure.

Code Snippet

https://github.com/sherlock-audit/2024-04-titles/blob/2ac20d07d0b4562c0b0ee15e1becbf786f0ed896/wallflower-contract-v2/src/editions/Edition.sol#L304-L320

Tool used

Manual Review

Recommendation

Adjust the calculation of the mint fee to account for the total number of tokens being issued across all receivers

    function mintBatch(
        address[] calldata receivers_,
        uint256 tokenId_,
        uint256 amount_,
        bytes calldata data_
    ) external payable {
        // wake-disable-next-line reentrancy
        FEE_MANAGER.collectMintFee{value: msg.value}(
-            this, tokenId_, amount_, msg.sender, address(0), works[tokenId_].strategy
+            this, tokenId_, amount_ * receivers_.length, msg.sender, address(0), works[tokenId_].strategy
        );

        for (uint256 i = 0; i < receivers_.length; i++) {
            _issue(receivers_[i], tokenId_, amount_, data_);
        }

        _refundExcess();
    }

Duplicate of #264