Weather Witness

First Flight #40
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

Incorrect Weather Classification: 800 (Clear) Misclassified as Cloudy Due to Overlapping Logic

Root + Impact

Description

  • In the GetWeather.js script used by Chainlink Functions is responsible for converting weather data from the OpenWeather API into an integer enum value representing the weather condition (e.g., SUNNY, RAINY, CLOUDY, etc.).

  • The script uses weather_id === 800 to classify clear weather and parseInt(weather_id / 100) === 8 to classify clouds. However, since 800 satisfies both conditions, the second conditional overwrites the first, causing clear weather to be misclassified as cloudy.

// ref: https://openweathermap.org/weather-conditions
// clear
if (weather_id === 800) weather_enum = 0;
@> // cloudy
@> else if (weather_id_x === 8) weather_enum = 1;

Risk

Likelihood:

  • This occurs whenever the weather condition ID from OpenWeather is exactly 800, which is very common (indicating clear skies).

  • The conditions are ordered such that the broader check (weather_id_x === 8) overrides the exact match for clear skies.

Impact:

  • Incorrect weather classification leads to wrong NFT metadata and user-facing weather state.

  • The image URI, NFT logic, and automation tied to weather enum become inconsistent or misleading.


Proof of Concept

Here is a test code which stimulates the response form OpenWeather

// Simulated response from OpenWeather
const weatherResponse = {
data: {
weather: [{ id: 800 }]
}
};
const weather_id = weatherResponse.data.weather[0].id; // 800
const weather_id_x = parseInt(weather_id / 100); // 8
let weather_enum = 1;
if (weather_id == 2) weather_enum = 3;
else if (weather_id === 800) weather_enum = 0; // intended: SUNNY
else if (weather_id_x === 8) weather_enum = 1; // also true → overwrites to CLOUDY
else weather_enum = 4;
console.log("Final weather_enum:", weather_enum); // Output: 1 → CLOUDY (wrong)

Recommended Mitigation

This guarantees that 800 is uniquely classified as SUNNY, and other 80x values (like 801, 802, 803, 804) correctly fall under CLOUDY

- // clear
- else if (weather_id === 800) weather_enum = 0;
- // cloudy
- else if (weather_id_x === 8) weather_enum = 1;
+ if (weather_id === 800) {
+ weather_enum = 0; // clear
+ } else if (weather_id_x === 2) {
+ weather_enum = 3; // thunderstorm
+ } else if (weather_id_x === 3 || weather_id_x === 5) {
+ weather_enum = 2; // rain
+ } else if (weather_id_x === 6) {
+ weather_enum = 5; // snow
+ } else if (weather_id_x === 8) {
+ weather_enum = 1; // cloudy
+ } else {
+ weather_enum = 4; // windy (fallback)
+
Updates

Appeal created

bube Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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