The fulfillMintRequest
function lacks caller validation, allowing:
Any address to trigger the minting process using a valid requestId
.
The NFT to be minted to msg.sender
(the arbitrary caller) instead of the original requester (_userMintRequest.user
).
Example Attack Flow:
Alice pays ETH and calls requestMintWeatherNFT
(generating requestId=123
).
Bob front-runs Alice and calls fulfillMintRequest(123)
.
Bob receives Alice’s NFT without paying ETH or initiating the request.
Critical Severity: Attackers can:
Steal NFTs intended for legitimate users.
Drain value from the system by minting unlimited NFTs at zero cost.
Disrupt user trust in the protocol’s core functionality.
Direct Violation of Business Logic: The minting process fails to enforce user-to-NFT ownership binding, rendering the payment mechanism (ETH mint fee) meaningless.
Publicly Exposed Request IDs: The requestId
generated during requestMintWeatherNFT
is emitted in the WeatherNFTMintRequestSent
event, making it visible on-chain. Attackers can trivially monitor these events to harvest valid requestId
values.
No Caller-Request Binding: The fulfillMintRequest
function does not validate whether the caller owns the original mint request. Combined with the public requestId
, this allows anyone to trigger the minting process for any pending request.
Theft of Paid NFTs: Users who pay the ETH mint fee lose their NFTs to attackers who call fulfillMintRequest
first.
Protocol Fund Drain: Attackers mint NFTs at zero cost while legitimate users’ ETH payments are irrecoverably locked in the contract.
Legitimate User Action:
Alice calls requestMintWeatherNFT
, pays s_currentMintPrice
ETH, and receives a requestId
(e.g., 0x123
).
Attacker Action:
Bob monitors the WeatherNFTMintRequestSent
event and extracts Alice’s requestId
.
Bob immediately calls fulfillMintRequest(0x123)
.
Result:
The NFT is minted to Bob’s address (msg.sender
), not Alice’s.
Alice’s ETH payment is retained by the contract, but she receives no NFT.
Zero-Cost Exploit: Attackers pay only gas fees, bypassing the ETH mint fee.
Repeatable: The attack can be executed for every valid requestId
emitted by the contract.
No Time Constraints: Attackers can exploit old/unfulfilled requests indefinitely.
New
There is no check to ensure that the caller of the `fulfillMintRequest` function is actually the owner of the `requestId`. This allows a malicious user to receive a NFT that is payed from someone else.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.