Skip to content

fix: credit score integer division loses sub-day precision for days_late calculation #374

@thewealthyplace

Description

@thewealthyplace

Bug

contracts/credit_score/src/lib.rsdays_late is computed as:

let days_late = (paid_at - due_date) / SECS_PER_DAY;

Integer division truncates. A payment made 23 hours 59 minutes late is classified as days_late = 0 — identical to an on-time payment. A payment 25 hours late is days_late = 1. The 1-hour difference between "23:59 late" and "25:01 late" results in dramatically different credit outcomes.

Fix

Use ceiling division so any partial day counts as a full day late:

let secs_late = paid_at.saturating_sub(due_date);
let days_late = (secs_late + SECS_PER_DAY - 1) / SECS_PER_DAY;

Document the rounding policy in a comment. Also apply saturating_sub so on-time payments (where paid_at <= due_date) yield days_late = 0 without panic.

Acceptance Criteria

  • Payment 23h 59m late → days_late = 1 (ceiling)
  • Payment exactly on due_date → days_late = 0
  • Payment 25h late → days_late = 2
  • Rounding policy documented in a code comment
  • Unit tests for all three boundary cases

References

  • contracts/credit_score/src/lib.rsdays_late calculation, ~line 238

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions