Skip to content

Commit 4cec7a0

Browse files
Hiksangclaude
andcommitted
Fix health factor overflow panic and enrich position response
- Handle U256::MAX health factor (no debt) without panic - Return collateral/debt USD values and LTV from getUserAccountData - health_factor: null when no debt (was crashing with overflow) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e209ff0 commit 4cec7a0

1 file changed

Lines changed: 45 additions & 6 deletions

File tree

crates/defi-protocols/src/lending/aave_v3.rs

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,19 +212,58 @@ impl Lending for AaveV3 {
212212
DefiError::RpcError(format!("[{}] getUserAccountData failed: {e}", self.name))
213213
})?;
214214

215-
let hf = u256_to_f64(result.healthFactor) / 1e18;
215+
let hf_raw = u256_to_f64(result.healthFactor) / 1e18;
216+
// Aave returns uint256.max for health factor when there's no debt
217+
let hf = if hf_raw.is_infinite() || hf_raw > 1e18 {
218+
None // No debt — health factor is effectively infinite
219+
} else {
220+
Some(hf_raw)
221+
};
222+
223+
// Collateral and debt in base currency (USD with 8 decimals in Aave V3)
224+
let collateral_usd = u256_to_f64(result.totalCollateralBase) / 1e8;
225+
let debt_usd = u256_to_f64(result.totalDebtBase) / 1e8;
226+
let ltv_bps = u256_to_f64(result.ltv);
227+
228+
// Build summary supply/borrow entries from aggregate data
229+
let supplies = if collateral_usd > 0.0 {
230+
vec![PositionAsset {
231+
asset: Address::ZERO,
232+
symbol: "Total Collateral".to_string(),
233+
amount: result.totalCollateralBase,
234+
value_usd: Some(collateral_usd),
235+
}]
236+
} else {
237+
vec![]
238+
};
239+
240+
let borrows = if debt_usd > 0.0 {
241+
vec![PositionAsset {
242+
asset: Address::ZERO,
243+
symbol: "Total Debt".to_string(),
244+
amount: result.totalDebtBase,
245+
value_usd: Some(debt_usd),
246+
}]
247+
} else {
248+
vec![]
249+
};
216250

217251
Ok(UserPosition {
218252
protocol: self.name.clone(),
219253
user,
220-
supplies: vec![],
221-
borrows: vec![],
222-
health_factor: Some(hf),
223-
net_apy: None,
254+
supplies,
255+
borrows,
256+
health_factor: hf,
257+
net_apy: Some(ltv_bps / 100.0), // LTV in percent
224258
})
225259
}
226260
}
227261

228262
fn u256_to_f64(v: U256) -> f64 {
229-
v.to::<u128>() as f64
263+
// U256::MAX doesn't fit in u128; handle gracefully
264+
if v > U256::from(u128::MAX) {
265+
f64::INFINITY
266+
} else {
267+
v.to::<u128>() as f64
268+
}
230269
}

0 commit comments

Comments
 (0)