Skip to content

[PR #34] f64_to_1e18(1.05) underflows by 128 ULP; boundary test bypasses conversion #105

@obchain

Description

@obchain

PR: #34 (feat/09-health-scanner)
File: crates/charon-scanner/src/scanner.rs
Lines: f64_to_1e18() helper (~L195), classify_partitions_positions_into_three_buckets test (~L230)

Problem: f64 cannot exactly represent 1.05. Nearest IEEE-754 double: 1.0499999999999999555910790149937383830547332763671875. Multiplied by 1e18 and truncated to u128: 1_049_999_999_999_999_872, not 1_050_000_000_000_000_000.

Consequence: any position with health_factor in [1_049_999_999_999_999_873, 1_050_000_000_000_000_000] classified as Healthy when should be NearLiquidation. Watched at COLD cadence instead of pre-cached for immediate liquidation.

Unit test constructs boundary value as hardcoded u128 literal (1_050_000_000_000_000_000u128) and asserts Healthy — passes because that value is above actual (lower) threshold. Test does not call f64_to_1e18(1.05) and compare; never exercises real boundary.

Fix: Replace f64 threshold input with string or basis-point integer (near_liq_threshold_bps: u32 = 10500 → multiply by 1e14 in integer arithmetic). If f64 kept, round to nearest integer after scaling rather than truncating, and add test calling f64_to_1e18(near_liq) and verifying equality with U256::from(1_050_000_000_000_000_000u128).

Metadata

Metadata

Assignees

No one assigned

    Labels

    layer:rustRust crates (core / scanner / protocols / executor / cli)pr-reviewFindings from PR review processpriority:p1-coreCore MVP scopetype:testTests, fuzz, fork, integration

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions