Skip to content

Commit e5cdbd5

Browse files
Copilot0xrinegade
andcommitted
ROUND 2: Fix business logic vulnerabilities - fetch error handling, async operations safety
Co-authored-by: 0xrinegade <[email protected]>
1 parent 568cffe commit e5cdbd5

File tree

2 files changed

+57
-44
lines changed

2 files changed

+57
-44
lines changed

src/utils/ccai.ts

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,35 @@ export const getTokensData = async () => {
88
}
99
`;
1010

11-
return await fetch('https://api.cryptocurrencies.ai/graphql', {
12-
method: 'POST',
13-
headers: {
14-
'Content-Type': 'application/json',
15-
},
16-
body: JSON.stringify({
17-
operationName: 'getDexTokensPrices',
18-
query: getDexTokensPrices,
19-
}),
20-
})
21-
.then((data) => data.json())
22-
.then((data) => {
23-
const map = new Map();
11+
try {
12+
const response = await fetch('https://api.cryptocurrencies.ai/graphql', {
13+
method: 'POST',
14+
headers: {
15+
'Content-Type': 'application/json',
16+
},
17+
body: JSON.stringify({
18+
operationName: 'getDexTokensPrices',
19+
query: getDexTokensPrices,
20+
}),
21+
});
2422

25-
if (data && data.data && data.data.getDexTokensPrices) {
26-
data.data.getDexTokensPrices.forEach((tokenData) => {
27-
map.set(tokenData.symbol, tokenData.price);
28-
});
29-
}
23+
if (!response.ok) {
24+
throw new Error(`HTTP error! status: ${response.status}`);
25+
}
3026

31-
return map;
32-
});
27+
const data = await response.json();
28+
const map = new Map();
29+
30+
if (data && data.data && data.data.getDexTokensPrices) {
31+
data.data.getDexTokensPrices.forEach((tokenData) => {
32+
map.set(tokenData.symbol, tokenData.price);
33+
});
34+
}
35+
36+
return map;
37+
} catch (error) {
38+
// Return empty map on error to prevent app crashes
39+
console.warn('Failed to fetch token prices:', error);
40+
return new Map();
41+
}
3342
};

src/utils/markets.ts

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -52,31 +52,35 @@ class PriceStore {
5252
}
5353
if (this.cache[marketName] === undefined) {
5454
let CORS_PROXY = "https://ancient-peak-37978.herokuapp.com/"
55-
fetch(`${CORS_PROXY}https://serum-api.bonfida.com/orderbooks/${marketName}`).then(
56-
(resp) => {
57-
resp.json().then((resp) => {
58-
if (!resp || !resp.data || !resp.data.asks || !resp.data.bids) {
59-
resolve(null)
60-
return
61-
}
55+
fetch(`${CORS_PROXY}https://serum-api.bonfida.com/orderbooks/${marketName}`)
56+
.then((resp) => {
57+
if (!resp.ok) {
58+
throw new Error(`HTTP error! status: ${resp.status}`);
59+
}
60+
return resp.json();
61+
})
62+
.then((resp) => {
63+
if (!resp || !resp.data || !resp.data.asks || !resp.data.bids) {
64+
resolve(null)
65+
return
66+
}
6267

63-
if (resp.data.asks.length === 0 && resp.data.bids.length === 0) {
64-
resolve(null);
65-
} else if (resp.data.asks.length === 0) {
66-
resolve(resp.data.bids[0].price);
67-
} else if (resp.data.bids.length === 0) {
68-
resolve(resp.data.asks[0].price);
69-
} else {
70-
const mid =
71-
(resp.data.asks[0].price + resp.data.bids[0].price) / 2.0;
72-
this.cache[marketName] = mid;
73-
resolve(this.cache[marketName]);
74-
}
75-
});
76-
},
77-
).catch(e => {
78-
resolve(null)
79-
});
68+
if (resp.data.asks.length === 0 && resp.data.bids.length === 0) {
69+
resolve(null);
70+
} else if (resp.data.asks.length === 0) {
71+
resolve(resp.data.bids[0].price);
72+
} else if (resp.data.bids.length === 0) {
73+
resolve(resp.data.asks[0].price);
74+
} else {
75+
const mid =
76+
(resp.data.asks[0].price + resp.data.bids[0].price) / 2.0;
77+
this.cache[marketName] = mid;
78+
resolve(this.cache[marketName]);
79+
}
80+
})
81+
.catch(e => {
82+
resolve(null)
83+
});
8084
} else {
8185
return resolve(this.cache[marketName]);
8286
}

0 commit comments

Comments
 (0)