Problem
When a loan is approved via approve_loan(), the creditline
contract does not actually pull funds from the liquidity
pool contract. The approval is purely a status change.
There is no atomic linkage between the pool and the loan.
Funds are never actually moved on-chain when a loan is
approved.
Context
In a real BNPL protocol the liquidity pool must lock
capital against approved loans. Without this the pool
balance and loan balances are completely disconnected.
A sponsor could withdraw all funds while loans are
active. This is a critical protocol correctness issue.
Before Starting
Read these context files:
- context/architecture-context.md
- context/code-standards.md
- contracts/creditline-contract/src/lib.rs
- contracts/liquidity-pool-contract/src/lib.rs
What To Build
-
Add cross-contract call in approve_loan():
After transitioning status to Active,
call liquidity_pool.lock_funds(loan_id, amount)
This marks that amount as locked in the pool.
-
Add lock_funds(env, loan_id, amount) to liquidity pool:
- require_auth() for creditline contract address
- Verify available_liquidity >= amount
- Deduct from available_liquidity
- Add to locked_liquidity
- Store mapping: loan_id -> locked_amount
-
Add release_funds(env, loan_id) to liquidity pool:
Called when loan is fully repaid.
Moves locked amount back to available plus interest.
-
Add liquidate_funds(env, loan_id) to liquidity pool:
Called when loan defaults.
Distributes locked funds according to loss policy.
-
Update creditline repay_installment():
On final installment, call pool.release_funds()
-
All cross-contract calls must be atomic.
If pool.lock_funds() fails, approve_loan() must revert.
Files To Touch
- contracts/creditline-contract/src/lib.rs
- contracts/liquidity-pool-contract/src/lib.rs
- contracts/liquidity-pool-contract/src/types.rs
- contracts/creditline-contract/src/tests.rs
- contracts/liquidity-pool-contract/src/tests.rs
Acceptance Criteria
Mandatory Checks Before PR
Problem
When a loan is approved via approve_loan(), the creditline
contract does not actually pull funds from the liquidity
pool contract. The approval is purely a status change.
There is no atomic linkage between the pool and the loan.
Funds are never actually moved on-chain when a loan is
approved.
Context
In a real BNPL protocol the liquidity pool must lock
capital against approved loans. Without this the pool
balance and loan balances are completely disconnected.
A sponsor could withdraw all funds while loans are
active. This is a critical protocol correctness issue.
Before Starting
Read these context files:
What To Build
Add cross-contract call in approve_loan():
After transitioning status to Active,
call liquidity_pool.lock_funds(loan_id, amount)
This marks that amount as locked in the pool.
Add lock_funds(env, loan_id, amount) to liquidity pool:
Add release_funds(env, loan_id) to liquidity pool:
Called when loan is fully repaid.
Moves locked amount back to available plus interest.
Add liquidate_funds(env, loan_id) to liquidity pool:
Called when loan defaults.
Distributes locked funds according to loss policy.
Update creditline repay_installment():
On final installment, call pool.release_funds()
All cross-contract calls must be atomic.
If pool.lock_funds() fails, approve_loan() must revert.
Files To Touch
Acceptance Criteria
Mandatory Checks Before PR