Skip to content

Feature/multi investor factoring payer role#59

Merged
Jayrodri088 merged 7 commits intoStellarState:mainfrom
caxtonacollins:feature/multi-investor-factoring-payer-role
Mar 27, 2026
Merged

Feature/multi investor factoring payer role#59
Jayrodri088 merged 7 commits intoStellarState:mainfrom
caxtonacollins:feature/multi-investor-factoring-payer-role

Conversation

@caxtonacollins
Copy link
Copy Markdown
Contributor

Multi-Investor Factoring with Payer Role Enforcement

Overview

This PR implements four interconnected features for the invoice-escrow contract to support decentralized factoring with multiple investors, explicit discount modeling, and enhanced security through payer role enforcement.

Issues Closed

Closes #29 : Use checked math for invoice-token total_supply on burn
Closes #33 : Enforce correct payer role in invoice-escrow record_payment
Closes #39 : Model factoring discount (face value vs investor purchase price)
Closes #43 : Partial/multi-investor funding (MVP slice)

Key Changes

Issue #29: Checked Math for Burn Operations

  • Replaced plain subtraction with checked_sub() in burn() and burn_from()
  • Returns Overflow error on underflow to prevent edge-case issues
  • Improves defensive programming for smart contracts

Issue #33: Payer Role Enforcement

  • Added debtor field to EscrowData to track authorized invoice payer
  • Added InvalidPayer error type
  • Updated create_escrow() to accept debtor parameter
  • Enforces payer == debtor check in record_payment()
  • Prevents unintended settlement triggers from unauthorized parties

Issue #39: Factoring Discount Model

  • Added face_value field: what the debtor owes (amount to be paid at settlement)
  • Added purchase_price field: what investors pay (discount applied here)
  • Updated create_escrow() signature to accept both values
  • Updated fund_escrow() to use purchase_price for investor funding
  • Updated record_payment() to settle based on face_value
  • Updated refund() to use purchase_price for collateral calculation
  • Events now include both values for indexer reconstruction

Issue #43: Multi-Investor Funding MVP

  • Added funded_amt field to track total funding progress
  • Added funder field (MVP: stores primary funder for distribution)
  • Added FunderAmount storage key for per-funder tracking
  • Updated fund_escrow() to accept amount parameter for partial funding
  • Implemented pro-rata distribution in record_payment() and refund()
  • Multiple investors can fund until purchase_price is reached
  • Status transitions to Funded only when fully subscribed

API Changes

create_escrow

Old: (invoice_id, seller, amount, due_date, payment_token, invoice_token)
New: (invoice_id, seller, debtor, face_value, purchase_price, due_date, payment_token, invoice_token)

fund_escrow

Old: (invoice_id, buyer)
New: (invoice_id, buyer, amount)

Test Coverage

  • 32 tests passing
  • 15 tests updated for new API signatures
  • Tests cover:
    • Checked math for burn operations
    • Payer role enforcement (correct/incorrect payer)
    • Factoring discount scenarios
    • Partial payment lifecycle
    • Multi-investor funding (MVP with single funder)
    • Pro-rata distribution
    • Refund scenarios

Implementation Notes

MVP Design Choice

For the MVP, we support multiple funders with per-address tracking but distribute pro-rata based on contribution. The funder field stores the primary funder for backward compatibility with existing tests. Future phases can extend this to track all funders in a list and distribute individually.

Pro-Rata Distribution Formula

pro_rata_share = (funder_amount / total_funded) * payment_amount

Fee Application

Fees are calculated on the payment amount (not face_value), ensuring consistent economics:

platform_fee = (payment_amount × fee_bps) / 10000
investor_amount = payment_amount - platform_fee

Backward Compatibility

  • Single-funder scenarios work identically to before
  • Tests use seller as debtor (simplified for MVP)
  • All existing functionality preserved

Future Enhancements

  • Track all funders in a list for full multi-investor support
  • Implement invoice token redemption for investor claims
  • Add funder-specific settlement tracking
  • Support partial refunds for multiple funders

…ions

- Replace plain subtraction with checked_sub in burn() and burn_from()
- Return Overflow error on underflow to prevent edge-case issues
- Maintains backward compatibility for valid burn amounts
- Improves defensive programming for smart contracts
- Export EscrowStatus from invoice-escrow lib for external use
- Fix payment-distributor integration tests with new API signatures
- Update test debtor parameters to use payer where record_payment is called
- Fix event assertions to match new event signatures
- All invoice-escrow tests passing (47/47)
- Payment-distributor tests have pre-existing auth issues unrelated to these changes
…com:caxtonacollins/SS-contracts into feature/multi-investor-factoring-payer-role
@Jayrodri088 Jayrodri088 merged commit 404e72f into StellarState:main Mar 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants