Skip to content

core: add liquidity reservation and locking for concurrent loan creation #81

Description

@EmeditWeb

Problem

loans.service.createLoan() reads available pool liquidity during credit
assessment, then builds the funding XDR for the user to sign. Nothing
reserves that liquidity between the check and on-chain settlement, so two
concurrent loan requests can each pass the availability check against the
same funds. The second fund_loan then reverts on-chain with
InsufficientLiquidity after the user has already signed — wasting fees
and leaving a dangling provisional loan. There is no distributed lock or
reservation around the assess → build → submit sequence.

Before Starting

Read ALL of these before writing any code:

  • context/architecture-context.md
  • context/code-standards.md
  • context/progress-tracker.md

What To Build

A liquidity reservation layer that serializes commitment of pool funds:

  1. A Redis-backed distributed lock (or reservation ledger) keyed to the pool
    so concurrent loan creations cannot over-commit available liquidity.
  2. Reserve the assessed amount atomically before returning the funding XDR;
    release the reservation on confirmed settlement, on failure, or on TTL
    expiry so a signed-but-never-submitted loan cannot lock funds forever.
  3. Reconcile reservations against on-chain locked_liquidity so reservations
    never drift from reality.

Files To Touch

  • src/modules/loans/loans.service.ts
  • src/modules/liquidity/* (reservation ledger)
  • src/common/* (Redis lock utility)
  • corresponding *.spec.ts

Acceptance Criteria

  • Concurrent loan creations cannot over-commit available liquidity
  • Reservation acquired before funding XDR is returned
  • Reservations expire (TTL) and release on failure/settlement
  • Reservation totals reconciled against on-chain locked liquidity
  • Concurrency test proves no double-spend under parallel requests

Mandatory Checks Before Opening PR

  • All context/ files read and understood
  • context/progress-tracker.md updated
  • npm run build passes with zero TypeScript errors
  • npm test passes — test count not decreased
  • No new any types introduced
  • Swagger decorators on any new endpoint
  • Migration file created for any schema changes
  • PR references this issue number

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    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