Skip to content

[Feature] Add per-installment late fee accrual #99

Description

@EmeditWeb

Problem

The RepaymentInstallment struct in contracts/creditline-contract/src/types.rs carries no due_date, and repay_installment() does not penalize late payments. Borrowers can effectively pay months late with zero consequence, which breaks the reputation score's underlying assumption that on-time payment matters.

Context

Late fees are the protocol's only economic enforcement mechanism short of liquidation. Without them, sponsors price all risk into the base APR, hurting on-time learners. The fee must flow back into the liquidity pool so sponsors are made whole.

Before Starting

Read these context files first:

  • context/architecture-context.md
  • context/code-standards.md
  • context/progress-tracker.md
  • contracts/creditline-contract/src/types.rs
  • contracts/creditline-contract/src/lib.rs

What To Build

  1. Add pub due_date: u64 to RepaymentInstallment in types.rs. Populate at loan creation: due_date = approval_ts + (n+1) * installment_period_secs.
  2. Add pub late_fee_bps: u32 to ProtocolParameters in types.rs, default 500 bps (5%).
  3. In repay_installment(), compute now = env.ledger().timestamp(). If now > installment.due_date, compute late_fee = installment.amount * late_fee_bps / 10_000 and require the caller to transfer installment.amount + late_fee.
  4. Route the late fee to the liquidity pool via cross-contract call, not the borrower's loan balance.
  5. Emit a LATEFEEPAID event with (loan_id, installment_index, fee_amount).
  6. Add 4 unit tests: on-time path (no fee), 1-day-late, exact-due-date boundary, custom-bps test.

Files To Touch

  • contracts/creditline-contract/src/types.rs
  • contracts/creditline-contract/src/lib.rs
  • contracts/creditline-contract/src/storage.rs
  • contracts/creditline-contract/src/events.rs
  • contracts/creditline-contract/src/tests.rs

Acceptance Criteria

  • due_date is set on every installment at loan creation
  • late_fee_bps is configurable and persisted in ProtocolParameters
  • Late fees route to the liquidity pool, not the loan balance
  • On-time payments incur zero fee (exact now == due_date is on-time)
  • 4 new tests pass
  • Migration note added: existing loans without due_date are gracefully handled (assume 0 = on-time)

Mandatory Checks Before PR

  • cargo build passes with zero errors
  • cargo test — all 93 existing tests still pass
  • require_auth() is FIRST line of every mutating function
  • extend_ttl() called after EVERY persistent storage write
  • New unit tests written for every new function
  • context/progress-tracker.md updated

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions