Skip to content

Reserve Auction can be bypassed#

High Risk

In Minting.sol there is metaMint function that is used for gasless minting. It states that it can only be used for free mints, as signature data does not handle transfer of funds from signer. However, that is not true. ERC20 tokens can be transferred from the signer if he gives the Canvas contract approval. That by itself is not problematic, since there is nothing wrong if minting with signature enables non-free mints also. The problem is that even if the canvas is on reserve auction, it executes defaultMint instead of mintReserveAuction.

Example#

  1. User A creates a canvas and sets it up for a reserve auction.
  2. User B signs a mint request for that canvas and calls metaMint, which executes defaultMint.
  3. User B buys the canvas at salePrice, which is the "starting bid price" of the auction.
  4. Because there was no bid made, user C can still make a bid on the auction. But he will not be able to mint, because oneMinted is already true.

Recommendation#

In metaMint add a check if reserveAuction is true. You can then disable reserve auctions by reverting, or you can execute mintReserveAuction.

Schema.MintRequest memory mintRequest = getMintRequest(data);

if (!canvasStorage().canvas[canvasId].reserveAuction) {
    defaultMint(msgSender, canvasId, 0, mintRequest);
} else {
    mintReserveAuction(msgSender, canvasId, mintRequest.selectedTraits);
    emit OneMinted(msgSender, canvasId, mintRequest);
}