Weather Witness

First Flight #40
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: medium
Valid

Frontrunning risk due to shared mutable `s_currentMintPrice` state

Root + Impact

Description

  • The s_currentMintPrice variable is used to validate the user’s payment with:

require(msg.value == s_currentMintPrice, WeatherNft__InvalidAmountSent());
  • Immediately after this check, s_currentMintPrice is incremented by s_stepIncreasePerMint, creating a shared mutable state that changes every time the function is called. This allows a frontrunning scenario where:

    1. A user reads s_currentMintPrice off-chain and prepares a transaction with msg.value == s_currentMintPrice.

    2. Another user submits a transaction that gets mined first and increments the mint price.

    3. The first user's transaction reverts because msg.value is now lower than the updated price.


  • This race condition makes it difficult for users to reliably mint unless they monopolize block space or overpay for priority.

  • Also, one user's mint will increase price for others, which promotes the "early user subsidy".

Risk

Likelihood:

  • The state update occurs per call and is easily predictable and exploitable by frontrunners.

Impact:

  • Can cause failed user transactions, wasted gas, and poor UX. Potentially exploitable by bots to deny access or extract MEV

Recommended Mitigation

  • A simple fix would be to store the mint price per user before they mint

mapping(address => uint256) public userMintPrice;
function prepareMint() external {
userMintPrice[msg.sender] = s_currentMintPrice;
}
function requestMintWeatherNFT(...) external payable {
require(msg.value == userMintPrice[msg.sender], ...);
}
Updates

Appeal created

bube Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

The price of the token is increased before the token is minted

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.