[H-2] Premature Timestamp Update in performUpkeep() leads to Silent Failures and DoS Risk
The WeatherNft::performUpkeep()
function updates the lastFulfilledAt
timestamp before confirming that the Chainlink Functions request has successfully executed and updated the weather data.
This premature state change leads to a false positive in checkUpkeep(), which will return false until the heartbeat interval has passed, even if the previous update failed. As a result, no retry will be triggered during that interval, creating a silent denial of service for that NFT's weather update.
In addition, silent failures occur in both the fulfillMintRequest()
and _fulfillWeatherUpdate()
functions:
This early return prevents further execution when the Chainlink Functions request fails, but does not emit any event or log the error. As a result, we will have not updated NFTs and blocked retry of the performUpkeep till the time has passed.
Both contribute to a poor user experience and complicate debugging or monitoring of failed Chainlink executions.
Likelihood:
Reason 1
High Likelihood: This issue can occur at any time due to external factors like billing, gas limits, or function errors.
Impact:
Impact 1
High Severity: This issue breaks the core functionality of the protocol — the automatic weather updates for NFTs. If a Chainlink Functions call fails, it is not retried, leaving NFTs outdated indefinitely. Users may believe their NFTs are up to date while in fact, they are not.
We have updated the lastFulfilledAt but the nft has failed to be updated. The time for the next retry has been restarted.
We recommend to delay the update of lastFulfilledAt
until the weather update has been successfully processed in WeatherNft::_fulfillWeatherUpdate()
Handle errors explicitly in WeatherNft::_fulfillWeatherUpdate()
:
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.