Weather Witness

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

Unrestricted NFT Minting by Users

Root + Impact

Description
The contract does not impose a limit on the number of NFTs a single user can mint, enabling potential abuse and market manipulation.

function requestMintWeatherNFT(
string memory _pincode,
string memory _isoCode,
bool _registerKeeper,
uint256 _heartbeat,
uint256 _initLinkDeposit
) external payable returns (bytes32 _reqId) {
require(
msg.value == s_currentMintPrice,
WeatherNft__InvalidAmountSent()
);
s_currentMintPrice += s_stepIncreasePerMint;
if (_registerKeeper) {
IERC20(s_link).safeTransferFrom(
msg.sender,
address(this),
_initLinkDeposit
);
}
_reqId = _sendFunctionsWeatherFetchRequest(_pincode, _isoCode);
emit WeatherNFTMintRequestSent(msg.sender, _pincode, _isoCode, _reqId);
s_funcReqIdToUserMintReq[_reqId] = UserMintRequest({
user: msg.sender,
pincode: _pincode,
isoCode: _isoCode,
registerKeeper: _registerKeeper,
heartbeat: _heartbeat,
initLinkDeposit: _initLinkDeposit
});
}

Risk
The requestMintWeatherNFT function lacks a mechanism to restrict the number of NFTs a user can mint.
Initial State: The system allows any user to call the minting function without restrictions.
Step 1: An attacker repeatedly calls requestMintWeatherNFT to mint a large number of NFTs.
Step 2: The attacker artificially inflates the price of NFTs due to the incremental mint price logic.
Outcome: The attacker gains an unfair advantage by manipulating the market and potentially reselling NFTs at inflated prices.
Implications: This can lead to market manipulation, reduced trust in the project, and unfair pricing for other users.

Impact:

  • NFT buyers and the project team:Buyers may overpay for NFTs, and the project team may face reputational damage.


Recommended Mitigation

To address this issue, introduce a mapping to track the number of NFTs minted by each user and enforce a maximum minting limit.

function requestMintWeatherNFT(
string memory _pincode,
string memory _isoCode,
bool _registerKeeper,
uint256 _heartbeat,
uint256 _initLinkDeposit
) external payable returns (bytes32 _reqId) {
require(
msg.value == s_currentMintPrice,
WeatherNft__InvalidAmountSent()
);
// Enforce the per-user minting limit
require(
s_userMintCount[msg.sender] < MAX_MINT_LIMIT,
"WeatherNft__MintLimitExceeded"
);
Updates

Appeal created

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

Multiple tokens for one `requestId`

The `WeatherNFT::fulfillMintRequest` allows a malicious user to call multiple times the function with the same `requestId`.

Support

FAQs

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