Weather Witness

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

Oracle Dependency Without Refund Mechanism

Root + Impact

Description: No Refund for Failed Oracle Requests

Summary
The contract does not refund users if the oracle fails to fulfill their mint request.

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 does not include a refund mechanism for failed oracle requests.
Initial State: A user sends the required mint price to the contract.
Step 1: The oracle fails to fulfill the mint request.
Outcome: The user loses their funds without receiving an NFT.
Implications: This can lead to user dissatisfaction and financial losses.

Impact:

  • Impact: NFT buyers.
    They Are Affected: Buyers lose funds without receiving the promised NFT.

Recommended Mitigation: To address this issue, implement a refund mechanism in the fulfillMintRequest function to return the mint price to the user if the oracle request fails.

  1. Emit Failure Event:

    • Emit a WeatherNFTMintRequestFailed event to log the failure and notify the user.


      2. Early Return:

      • If the oracle request fails, the function exits early to prevent further execution.

// Refund the user if the oracle request fails
if (response.length == 0 || err.length > 0) {
payable(_userMintRequest.user).transfer(s_currentMintPrice);
emit WeatherNFTMintRequestFailed(requestId, _userMintRequest.user);
return;
}
Updates

Appeal created

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

Lost fee in case of Oracle failure

If Oracle fails, the `fulfillMintRequest` function will not return the payed fee for the token to the user.

Support

FAQs

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