Skip to main content
The pool’s exit leaf is a NUMS point that nobody can sign. If the operator is unavailable, lenders and borrowers have no exit path: their virtual outputs cannot be spent, renewed, or exited, and they expire. See Exit.
A lending vault is five contracts. The pool is one. A lender deposit, a borrower deposit, a lender staging output, and a borrower staging output are the other four. The constructor of the pool names no lender and no borrower. Each standing output names payScript, the script that receives the token or the payout. Anyone may sweep that output. The sweep asks for no signature. The pool is one output, so one spend settles it. The standing outputs do not spend the pool when people fund them. One sweep spends the pool once and settles up to four of them. Output i settles input i. The next sweep spends the pool that sweep created. A lender deposit carries stablecoin. open creates the pool. sweep mints one lender share per stablecoin unit. A borrower deposit carries bitcoin. open creates the pool when it is first. sweep mints one collateral token per sat above the carrier. To leave, the holder sends the token to a staging output. That send is the authorization. A later sweep burns the token and pays payScript in the same spend. Lender shares pay stablecoin. Collateral tokens pay bitcoin. If any check fails, the emulator does not cosign, so the standing output and the pool stay as they were. refund pays a standing output back to payScript and does not spend the pool. borrow and repay stay on the pool. They spend one holder’s own token output, so they are not a shared standing address. borrow pays stablecoin and mints a debt token. The collateral tokens come back. repay burns the debt and returns the debt plus the fixed fee feeBps. There is no interest clock. The fee is added once, when the debt is repaid. satsPerUnit is fixed at deployment, and the vault has no liquidation path. The contract checks the collateral ratio only at that fixed rate, never at market price. A borrower can hold the stablecoin after the collateral’s market value falls below the debt, and no spend forces the position closed. Lenders bear the exchange-rate risk in full. A lender share that rounds to zero stablecoin fails that spend, and the shares stay on the staging output. The payout division truncates, so the remainder of every payout stays in the pool’s stablecoin balance, and only a repay adds stablecoin back. When the last lender exits and the supply is gone, a remainder stays on the pool for good. A collateral staging output must hold no debt, and the pool’s remaining bitcoin must still cover the open debt at satsPerUnit. A pool spend cannot share a transaction with an oracle read. The pool’s continuation and the attestation both require output 0 to carry their own script, and one output 0 cannot carry two scripts. Read the oracle in a separate transaction (Oracle Output). Two ledger assets remember the lender supply and the debt supply, so the pool script does not change and a continuation needs no new constructor. The exit leaf on the pool is the NUMS point (Exit). payScript is the receiver’s witness program. The asset ids, feeBps, satsPerUnit, and noExitKey on a standing output match the pool, or new LendingPool does not name this pool. serverExitDelay is not a parameter. The client binds it (CSV delays).
lending_pool.ark
lender_deposit.ark
borrower_deposit.ark
lender_exit.ark
borrower_exit.ark

Shared parameters

The four standing contracts add payScript. That is the witness program that receives the minted token, or the payout.

LendingPool

sweepLender spends the pool and one to four lender deposits. It checks that each output mints the stablecoin that input brought in. sweepBorrower spends the pool and one to four bitcoin deposits. It checks that each output mints the collateral that input brought in. borrow spends the pool, a collateral-token output, and 660 sats of carriers. It returns the collateral tokens, pays the stablecoin, and mints the debt token. The debt output carries 330 of the 660 sats. The other 330 sats stay in the transaction as a fee on every borrow, on top of feeBps on repay. repay spends the pool, a debt-token output, and a stablecoin output of the debt plus the fee. It burns the debt. withdrawLender spends the pool and one to four lender staging outputs. It burns the shares and checks each stablecoin payout. withdrawColl spends the pool and one to four borrower staging outputs. It burns the collateral tokens and checks each bitcoin payout. unilateral is the NUMS exit leaf. Nobody can spend it.

Standing outputs

LenderDeposit.open creates the pool from the first stablecoin deposit. sweep joins a later batch and requires output i to pay this output’s payScript. BorrowerDeposit.open creates the pool from the first bitcoin deposit. sweep joins a later batch the same way. LenderExit.exit requires output i to pay this output’s payScript the share of stablecoin for the shares on this output. BorrowerExit.exit requires output i to pay this output’s payScript one sat for each collateral token on this output. refund on each standing output pays that output back to payScript. The pool is not an input.