CreditFacility_v1). Each loan is a position in the market’s ReserveManager_v1, and the lent collateral comes from the market’s reserve.
The facility values locked tokens at the reference price, not at the buy price. When the buy price is close to the reference price, a borrow against newly bought tokens returns most of the collateral the buy spent, and that collateral can buy again. Repeated in one transaction, the same new collateral buys more supply than a single buy.
Parts of a loan
The origination fee is the fee charged on each amount lent. The code calls it the borrowing fee (
setBorrowingFeeRate, getBorrowingFeeRate). LTV (loan-to-value) is the share of the locked tokens’ value at the reference price that can be lent, in basis points.
A loan closes when its loan amount and locked tokens both reach zero through repayment, or when it is merged into another loan.
Borrowing
A borrower names the amount of collateral to borrow. The facility computes the issuance tokens that must be locked for that amount at the current reference price and LTV, and pulls them from the borrower. TheReserveManager_v1 opens a position, records the full amount as loan amount, and draws that amount from the market’s reserve. The facility sends the origination fee to the fee treasury and the rest to the borrower.
where:
- is the amount borrowed, in collateral (
requestedLoanAmount_). The loan amount starts at - is the number of issuance tokens locked
- is the loan-to-value ratio in basis points (
getLoanToValueRatio) - is the reference price, in collateral per token, 18 decimals (
getReferencePrice) - is the origination fee in basis points (
getBorrowingFeeRate)
Repaying
A borrower repays any part of the loan amount. The facility pulls the collateral, and theReserveManager_v1 returns it to the market’s reserve. Locked tokens are released in proportion to the share of the loan amount repaid. No fee is charged on a repayment.
where:
- is the amount the borrower offers (
repaymentAmount_) - is the loan amount before the repayment
- is the amount repaid. An amount above the loan amount repays the loan amount in full
- is the locked tokens before the repayment
- is the tokens released to the borrower, rounded down
Other loan functions
- Repay for another address.
repayFortakes collateral from the caller and releases tokens to the loan’s borrower. It reverts for a loan whose borrower reports theIPresaleClaimObligations_v1interface (a loan held by the early-access escrow). - Transfer.
transferLoanmoves a loan to a new borrower. The locked tokens and the loan amount do not change. The new borrower cannot be the current borrower or the zero address. - Merge.
consolidateLoansmerges two or more of the caller’s loans into one new loan. TheReserveManager_v1adds up the locked tokens and the loan amounts, closes the old positions, and opens one position with a new ID.
Rebalancing a loan
When the reference price increases, the same locked tokens support a larger loan.rebalanceLoan lends the difference between that larger amount and the current loan amount, against the tokens already locked. The origination fee applies to the new amount, and the loan amount increases by the full new amount.
where:
- is the amount the locked tokens support at the current reference price and LTV
- is the current loan amount
- is the new amount lent. The call reverts if is at or above
Looping
Looping is buying issuance tokens and borrowing against them, repeated in one transaction. Each repeat is a round: the facility buys on the curve with the collateral it holds, locks the tokens that buy minted, and borrows against them. The amount paid out by the borrow is the collateral for the next round.buyAndBorrow runs between 1 and the maximum rounds per transaction (getMaxLoops).
In each round:
- The facility buys on the market’s curve with all the collateral it holds for the call. The market takes the buy fee (Markets and curves).
- The facility borrows the most the minted tokens support: , rounded down. The tokens are locked in a new loan for the borrower.
- The origination fee goes to the fee treasury. The rest stays on the facility for the next round.
consolidate_ set, the facility merges the call’s loans into one.
where:
- is the collateral spent in round ; is the new collateral (
amount_) - is the market’s buy fee in basis points (
getBuyFee) - is the average price paid per token in the round. The formula holds when every round pays the same price, for example when all buys fall in one step
- is the share of each round’s collateral that carries into the next round
- is the tokens minted in round 1, and is the tokens minted over rounds
Buy price 2.20, :
The same 1,000 new collateral buys 1,983.12 tokens at a 10% premium and 664.77 tokens at a 120% premium. On a real curve each buy raises the buy price, so later rounds pay more per token than these single-step cases.
Where the lent collateral comes from
The facility does not hold a pool of its own. Each loan draws collateral from the market’s reserve through theReserveManager_v1, which is the only contract the curve accepts draws from.
drawReserves and restoreReserves move collateral out of and back into the reserve, the curve’s collateral balance. They do not change the curve’s virtual collateral supply (Markets and curves), and locking does not change the issuance token’s supply. Borrowing and repaying therefore do not move the curve’s price.
After each openPosition, draw, repay and mergePositions, the ReserveManager_v1 checks that the position’s loan amount is at or below its locked tokens × the reference price, rounded down. The call reverts otherwise. This check uses the full reference value; the facility applies LTV on top of it.
Example. For the 1,600 loan above, the reserve falls by 1,600 and the virtual collateral supply stays the same. The ReserveManager_v1 records 1,000 tokens locked and 1,600 loan amount, and its check compares 1,600 with 1,000 × 2.00 = 2,000.
Parameters
The launch route grants no role on the three setters, so only the holder of
DEFAULT_ADMIN_ROLE passes their permission check. The facility sends origination fees to the market’s fee treasury (Fees and routing).
Who can call what at launch
repay, transferLoan and rebalanceLoan also require the caller to own the loan. Authority lists every role.
Scenarios
Example: borrowing for liquidity elsewhere. An address locks 1,000 tokens at a reference price of 2.00, with LTV at 80% and the origination fee at 2%, and borrows 1,600. The borrower receives 1,568.00 collateral, as in the borrowing example, and deposits it in a pool outside the market. The market’s curve, reserve and loan record do not change after the deposit. On a connected market, the borrowed token is the issuance token of the base market.
Edge cases
- Zero inputs. A borrow amount, repayment amount or round count of 0 reverts.
- Too many rounds. A round count above the maximum rounds per transaction reverts.
- Minimum loan. When the origination fee is above 0, a loan below 10,000 ÷ fee bps base units, rounded up, reverts.
- Slippage on a loop.
buyAndBorrowtakes a minimum for the total tokens minted across all rounds, including locked tokens. Below it, the whole call reverts. - Rounding remainder. Locked tokens per round are rounded up from the loan, and the loan is rounded down from the tokens. Tokens left over from a round go to the borrower at the end of the call.
- Repayment release rounds down. A small repayment can release 0 tokens.
- Loan ownership.
repay,transferLoanandrebalanceLoanrevert for a loan the caller does not own.consolidateLoansreverts if any loan is not the caller’s, or if fewer than two loans are given. - Frozen market. The curve’s
drawReservesandrestoreReservesrevert while the market is frozen, so borrowing, looping, rebalancing and repaying revert. - Endowed markets. On a market with an endowment controller, draws revert while endowment setup is open or before activation. Each draw also reverts unless total loan amount plus endowment draws plus the new amount is at or below the reference price × the lower of supply and the reference segment’s size. See Endowed reference segment.
Code
Source:
house-markets/contracts at 0ebbc89a (branch integration/v12-post-qa).