Module 05: Lending
What this covers: Complete guide to BASIS loans: take, extend, repay, partial sell, and claim. Includes the vault loan cross-reference, the sell-vs-borrow decision, fees, and error recovery.
Prerequisites
- Wallet funded with the pair asset of the collateral's main (→01), client initialized (→02)
- Hold a token to use as collateral: bought via trading, created, or vesting
- Understand floor vs spot pricing: LTV math depends on token type
Next steps after borrowing
- Borrowed the pair asset? Redeploy it: another trade, stake the main, bet on a market, or create a token
- Want collateral that keeps earning? Use the vault loan path instead of regular
takeLoan() - Borrowed against a Floor+ token? See §6 of Module 04 for floor profit scenarios
- Stacking multiple loans? Read Module 12 for multi-path capital recycling
⚠️ This module covers hub loans, not leverage. Your leverage position is recorded on the token's main and has its own ids; hub loans are stored on the loan hub, keyed by a hub id per wallet. Hub-loan ids and leverage ids are separate counters: never pass one to the other's methods. If you used
leverageBuy(), manage that position through Module 04 §3c–3d: do NOT useclient.loans.extendLoan(),repayLoan(),claimLiquidation()orhubPartialLoanSell()on it. Close leverage withSWAP.partialLoanSellFor(main, positionId, percentage, true, minOut); extend, repay or claim it on its main withisLeverage = true.
Examples use the default main, STASIS (the USD main), whose pair asset is USDG (6 decimals). On another main read "STASIS" as that main and "USDG" as its pair asset, and use the pair asset's
decimals(). The mains of a deployment are listed in/contracts.json(mains[], each with its on-chainsymbol).
Why Borrow on BASIS
The single most important fact about BASIS loans: there is no price-based liquidation. Ever.
On every other DeFi platform, borrowing against a volatile asset means you live with margin call risk. One flash crash and your collateral is gone. On BASIS, a flash crash cannot liquidate your loan; the collateral can still lose value. Loans expire by time only: if your collateral drops in price mid-loan, the loan stays open. You choose when to exit: repay early, extend cheaply, or let it expire. An expired loan is closed by a keeper's liquidation transaction, not by the clock: see "On expiry" below.
Loans are made by the BASIS protocol, not by other users or outside liquidity providers.
Specific reasons to borrow instead of sell:
- Keep your upside. Selling forfeits future appreciation. Borrowing lets you hold the position while accessing capital. If the token 5x's after you borrow, you still own all of it.
- Capital works twice. You hold the token AND deploy the borrowed pair asset into another position simultaneously: see Module 12 for full stacking paths.
- Extensions are cheap. 400x cheaper per day than originating a new loan. You're never locked into a long commitment: take the minimum (
minDaysLoan(), 10 days today), extend as needed. - Any BASIS token works as collateral on its own main: the main itself and its factory tokens (Stable+, Floor+, Predict+, Meme+). A vault stake borrows through the vault (Module 06) and a vesting position through the vesting contract (Module 09).
- Collateral can appreciate. A Stable+ or Floor+ floor never decreases, so your collateral value may exceed your debt by expiry.
How It Works
The Basics
Deposit tokens as collateral → receive the pair asset of the collateral's main → repay before expiry to reclaim collateral.
Collateral value (read it with getColleteralValue(amount, token), the ABI's spelling, called on the collateral's main):
- A main (STASIS on the default main): valued at its spot price.
- A factory token: valued at its floor price (
calculateFloor()), not spot. At multiplier 100 (Stable+, Predict+) the floor equals the price, so you borrow the full market value; a Meme+ token at 100 borrows against its launch price. - Floor+: the gap between floor and spot is your built-in safety margin.
- The collateral must belong to the main you name (
wrong pair).
On expiry (if not repaid or extended): nothing happens by itself at liquidationTime.
- After
liquidationTimea keeper liquidates the position (ALiquidator.liquidate, keepers only). Assume it can happen in the first block after the deadline. Until that transaction lands a repay or a paid extension still goes through; do not plan on the gap. - The keeper closes the loan: the collateral that covers the debt is taken to repay it, for every token type. A loan is sized at the floor, which never falls, so its collateral is designed to cover the debt.
- 10% of the rest is the liquidation fee, and you claim the remainder, in the collateral token, with
claimLiquidation(hubId). It is NOT returned automatically: you must claim it. Claim within 365 days of the liquidation; after that the leftover may no longer be claimable. - If nothing is left, you lose the collateral. You never owe anything beyond it. No margin calls, no debt beyond collateral, no price liquidation.
The Cost Model
Interest is prepaid and non-refundable. There is no compounding, no accrual: you pay upfront for the days you request.
| Component | Rate | When Paid |
|---|---|---|
| Origination fee | 2% flat | Deducted upfront from the pair asset received |
| Daily interest | 0.005% per day | On collateral value, paid upfront |
| Extension fee | 0.005% per day | Paid upfront when extending |
These are today's values: the main's staticFeePercentage() (200 = 2%), dynamicFeePercentage() (5 = 0.005% per day), minDaysLoan() (10) and maxDaysLoan() (1000). Read them from the main.
Repayment amount: Read fullAmount from getUserLoanDetails(): this is the total obligation in the pair asset (the collateral's value at origination; you received it minus the prepaid fees). You repay this amount; no discount for early repayment.
Total cost by duration:
| Duration | Origination | Interest | Total Cost |
|---|---|---|---|
| 10 days (minimum today) | 2.00% | 0.05% | 2.05% |
| 30 days | 2.00% | 0.15% | 2.15% |
| 90 days | 2.00% | 0.45% | 2.45% |
| 365 days | 2.00% | 1.825% | 3.825% |
Optimal strategy: Always take the minimum duration (minDaysLoan(), 10 days today) and extend as needed. A 100-day extension costs 0.5% vs. a new 100-day loan costing 2.5%. Extensions are roughly 400x cheaper per day than re-originating.
Actions
Take a Loan
// JS
const MAIN = client.mainTokenAddress; // the default main. In general: the collateral itself when it is a main, else collateral.quoteToken()
const result = await client.loans.takeLoan(MAIN, collateralToken, parseUnits("100", 18), 10n);
// Python
result = client.loans.take_loan(MAIN, collateral_token, 100 * 10**18, 10)
Contract: LOANS.takeLoan(ecosystem, collateral, amount, daysCount); the collateral is approved to the loan hub.
| Param | Type | Description |
|---|---|---|
ecosystem | string | The collateral's main: the collateral itself when it is a main, otherwise collateral.quoteToken(). A wrong main reverts wrong pair; a main the hub does not serve reverts Ecosystem inactive |
collateral | string | Collateral token address |
amount | bigint/int | Collateral amount (18 decimals: every BASIS token has 18) |
daysCount | bigint/int | Loan duration in days: minDaysLoan() to maxDaysLoan() of the main (10 and 1000 today) |
Pre-flight checks:
- Verify you hold sufficient collateral balance (use
getTokens()for an overview). daysCountmust be withinminDaysLoan()andmaxDaysLoan()of the main (10 and 1000 today); outside it the call revertsincorrect loan duration. The collateral's value must reachminimumLoan()(Minimum loan amount not met).- One open loan per wallet per main and collateral token: with one open,
takeLoanrevertsOpen loan: increase it. Add collateral to it withincreaseLoan()instead. - Expected payout, in the pair asset of the collateral's main = value × (1 − 2% − 0.005% × days). Value is amount × spot price for a main and amount ×
calculateFloor()for a factory token. For 10 days: value × 0.9795.
Note: loans.takeLoan() is a simple one-layer loan. Your collateral is held by the loan and does NOT earn rewards. To keep earning vault rewards on the collateral while borrowing, use the vault loan path (vault.borrow()): covered in Module 06.
After the call: finding your hubId:
Take hubId from the hub's LoanCreated event in the receipt. getUserLoanCount(wallet) (on chain: the hub's userLoanCount(wallet)) is also the newest id. Use this numeric ID for getUserLoanDetails(), repayLoan(), extendLoan(), and all other loan operations. Do not pass token addresses as loan IDs: hubId is a number, not an address.
const loanCount = await client.loans.getUserLoanCount(walletAddress);
const hubId = loanCount; // ids start at 1: count equals the latest hubId
const details = await client.loans.getUserLoanDetails(walletAddress, hubId);
// details.collateralToken tells you which token backs this loan
Hub ID vs token address:
getUserLoanCount(wallet)returns the total loans ever created by this wallet across all tokens. Each loan gets a sequentialhubId. Ids start at 1; id 0 revertsLoan does not exist. To find loans for a specific token, enumerate from 1 to count, inclusive, and checkdetails.collateralToken; closed loans are returned too, so filter onactive.
Repay a Loan
Repay part of the debt, or all of it to get the collateral back. amount below the debt is a partial repay (the debt drops, the same share of the collateral comes back to you, the loan stays open, nothing is sold; what is left of the debt must stay at least the main's minimumLoan(), else Repay in full); at or above the debt is a full repay (exactly the debt is taken). Pass 2^256 - 1 to repay all.
// JS
const result = await client.loans.repayLoan(hubId, maxUint256); // 2^256 - 1 = repay all; a smaller amount repays part
// Python
result = client.loans.repay_loan(hub_id, 2**256 - 1)
- Contract:
LOANS.repayLoan(hubId, amount). Approve the pair asset of the loan's main (the hub'secosystems(main).stable) to the loan hub for at least the amount (the SDK does it).0revertsZero amount. A partial repay emits the hub'sLoanPartlyRepaid(user, hubId, amount, collateralReleased). - A full repay takes
fullAmount(fromgetUserLoanDetails()), not just the principal. - Repaying early does NOT save money: unused days are forfeited. Let loans run to near-expiry if you can.
Extend a Loan
Extend duration for 0.005%/day: approximately 400x cheaper than originating a new loan.
// JS
const result = await client.loans.extendLoan(hubId, 30n, true, false);
// (hubId, addDays, payInStable, refinance)
// Python
result = client.loans.extend_loan(hub_id, 30, True, False)
| Param | Type | Description |
|---|---|---|
hubId | bigint/int | Hub loan ID |
addDays | bigint/int | Days to add: minDaysLoan() to maxDaysLoan() (10 to 1000 today), or 0 together with refinance = true |
payInStable | boolean | true = pay the extension fee now, in the pair asset of the loan's main. false = the fee is added to the debt; that needs debt plus fee to stay below the collateral's value (Not enough collateral to cover fees) |
refinance | boolean | true = borrow again against the collateral's current value and receive the surplus. Cannot be combined with payInStable = true (Pay in stable or refinance, not both). With 0 days it needs at least 10 days left (Time remaining too short) |
Contract: LOANS.extendLoan(hubId, addDays, payInStable, refinance). 1 to 9 days revert incorrect loan duration. Pre-check with the main's extensionEligibility(user, loanId, days, isLeverage, payInMainPair, refinance) → (possible, fee, extraOut); for a hub loan pass the loan hub's address as user and the loan's internal id as loanId (coreLoanId from LOANS.userLoans(wallet, hubId)).
Critical rule: increaseLoan() needs strictly more than minDaysLoan() (10 today) days left on the loan, else it reverts Duration too short. Extend first.
Increase Collateral
Add more collateral to an existing loan without taking a new loan. The added value is borrowed out in the pair asset, minus the origination fee and the daily fee for the days left.
// JS
const result = await client.loans.increaseLoan(hubId, parseUnits("50", 18));
// Python
result = client.loans.increase_loan(hub_id, 50 * 10**18)
| Param | Type | Description |
|---|---|---|
hubId | bigint/int | Hub loan ID |
amountToAdd | bigint/int | Additional collateral (18 decimals) |
Pre-flight: Check remaining days. With 10 days or fewer left (minDaysLoan), call extendLoan() first or this reverts Duration too short. The added collateral must add borrowing power (No borrowing power).
Partial Sell
Close a share of the loan yourself (a self-liquidation): the collateral that covers that share of the debt is taken to repay it, with no tax, and the residual (the part of your collateral left to sell) is sold for you and paid in the pair asset. The residual sale is taxed like any normal sell of that token: the base fee plus the token's creator and rewards fees (getTaxRate(token, address(0)), no referral discount), split as a trade tax. A loan cannot be used to get out of a token more cheaply than selling it. On a main (for example STASIS) the sell rate is just the base fee.
// JS: regular hub loan only
const result = await client.loans.hubPartialLoanSell(hubId, 30n, false, minOut);
// (hubId, percentage, isLeverage=false, minOut)
// ⚠️ For leverage positions, use SWAP.partialLoanSellFor(main, id, pct, true, minOut) instead: see Module 04 §3d
Contract: LOANS.hubPartialLoanSell(hubId, percentage, minOut). It takes no isLeverage argument: the hub always sells with isLeverage = false.
minOut: never 0. Build it from MainLens.getPartialLoanSellAmounts(main, coreLoanId, loanHub, 30, false).residualTokens (coreLoanId, the loan's internal id, from LOANS.userLoans(wallet, hubId); loanHub the hub's address), then SWAP.getAmountsOut(residualTokens, [token, main, pairAsset]) ([main, pairAsset] when the collateral is the main), less the sell rate (getTaxRate(token, address(0))) and your tolerance. minOut is checked against what you receive, after that fee.
| Param | Type | Description |
|---|---|---|
hubId | bigint/int | Hub loan ID |
percentage | bigint/int | Must be a multiple of 10 (10, 20, 30 ... 100). Anything else reverts % by 10; outside 10 to 100 reverts % range. |
isLeverage | boolean | SDK argument only; always false. The contract call has no such argument |
minOut | bigint/int | Minimum pair asset you receive, after the sell-rate fee (slippage protection) |
Hard rule: Percentage must be exactly 10, 20, 30, 40, 50, 60, 70, 80, 90, or 100. Passing 25 or 33 reverts with % by 10. The result is in the LoanSold event on SWAP and PartialLoanSold on the hub.
⚠️ Leverage uses a different system. Your leverage position is recorded on the token's main, not in the loan hub → see Module 04 §3c–3d. Do NOT use hubPartialLoanSell for leverage.
Claim After Liquidation
After a keeper has liquidated an expired loan, claim what is left of the collateral: 90% of the collateral that was not needed for the debt, paid in the collateral token. Claim within 365 days of the liquidation; after that the leftover may no longer be claimable.
// JS
const result = await client.loans.claimLiquidation(hubId);
// Python
result = client.loans.claim_liquidation(hub_id)
Wait for the liquidation, not for the expiry time. Passing liquidationTime does not liquidate the loan; a keeper does. Until then claimLiquidation() reverts Loan is still active, and you can still repay or extend. Check getUserLoanDetails(wallet, hubId) first: isLiquidated is true and liquidationClaim is above 0. With nothing left it reverts Nothing to claim.
Do not forget to claim. The leftover does not come back by itself. Claim within 365 days of the liquidation; after that the leftover may no longer be claimable. Token prices keep moving until you claim.
Staking Loan Cross-Reference (Vault Loans)
The vault loan path gives you an extra layer: the pledged stake keeps earning rewards.
Flow:
Buy STASIS → stake it (vault.stake(main, amount))
→ borrow the pair asset (vault.borrow(main, stasisAmount, days))
Key differences from loans.takeLoan():
- The pledged stake keeps earning vault rewards from platform fees
- Uses the one vault (
SWAP.pairs(main).staking; SDKclient.vault(main)), with the main as the first argument of every call, notclient.loans - One loan per position: the vault allows one active loan per wallet per main. With a loan open,
borrow()revertsPosition active. Use addToLoan; calladdToLoan(main, additionalStasis)instead. - A vault loan is owned by the vault in the hub, so
client.loans.*fails for it (Invalid loan): always use the vault's own calls.
Check before borrowing:
const vault = client.vault(); // the default main's vault
const available = await vault.getAvailableStasis(wallet); // stake + unclaimed rewards - pledged
const pos = await vault.getPosition(wallet); // positions(main, user)
if (pos.hub === zeroAddress) await vault.borrow(available, 10n); // no open loan (hub unset); borrow(main, stasisAmount, days)
Vault methods (contract calls on the vault):
| Method | What It Does |
|---|---|
stake(main, amount) | Stake the main 1:1. Approve the main to the vault first. |
unstake(main, amount, toMainPair, minMainPair) | Take stake out; with toMainPair = true it is sold for the pair asset. The pledged part cannot leave. |
claim(main) / compound(main) | Take rewards out, or add them to the stake. |
borrow(main, stasisAmount, days) | Pledge that much stake and borrow the pair asset. One active loan per position. |
repay(main) | Repay fullAmount in the pair asset and release the pledge in the same call. Approve the pair asset to the vault. |
addToLoan(main, additionalStasis) | Pledge more stake into the open loan; needs more than 10 days left. |
extendLoan(main, days, payInMainPair, refinance) | Extend the vault loan at 0.005%/day. Always call it on the vault. |
Same fees as regular loans: 2% origination + 0.005%/day interest.
Full details: Module 06: Staking
Sell vs. Borrow Decision
Not every situation calls for a loan. Use this framework:
Borrow when:
- You believe the token will continue to appreciate: you want to keep the upside
- You need temporary liquidity (paying fees, entering another position, bridging capital)
- The collateral is a main or a vault stake: its price only rises in pair-asset units and a vault stake keeps earning, but the loan still expires on time and a liquidation takes the pledged collateral
- You want capital to work in two places simultaneously (a vault stake keeps earning rewards while the borrowed pair asset is deployed elsewhere)
Sell when:
- You want to lock in profit and exit the position (use
sell()) - You believe the price has peaked or the market is turning
- The loan cost (2% origination) exceeds the expected benefit of holding
- You need permanent liquidity, not temporary
Key insight for Floor+ positions: Your loan LTV is calculated against the floor price, but you can sell at the market price. When a Floor+ token has appreciated significantly, there's a large spread between what you owe (floor-based debt) and what the tokens are actually worth at market. Selling captures that entire spread. Borrowing only gives you the floor value in the pair asset while you wait.
The stacking play: The power of borrowing on BASIS is chaining. Each buy-then-borrow returns the input less the buy fee (getTaxRate(token, wallet), 0.60% on a main today) and the loan fee (2% plus 0.005% per day of the collateral value): about 97.4% of the pair asset for a 10-day loan on a main or a multiplier-100 token with no creator or rewards fee, less on a token with those fees, and a Floor+ token returns less by its floor-to-spot gap. Three stacks from $1,000 leave three positions and about $923 liquid: all from one starting bag, none of it price-liquidatable. Compute your own chain from those reads. See Module 12 for the full multi-path stack.
Fees Summary
| Action | Fee | Notes |
|---|---|---|
| Origination | 2% flat | Deducted upfront. One-time, non-refundable. |
| Daily interest | 0.005%/day | On collateral value, prepaid for full duration. |
| Extension | 0.005%/day | Same rate, paid upfront. ~400x cheaper than re-originating. |
| Repayment | Repay fullAmount | Includes prepaid interest. No discount for early repay. |
| Liquidation after expiry | A keeper closes the loan: the collateral that covers the debt is taken to repay it; 10% of the rest is the liquidation fee | Claim the remainder with claimLiquidation() within 365 days of the liquidation. |
| Partial sell (hub loan) | The token's sell rate on the residual sold: base + creator + rewards fee (getTaxRate(token, address(0))) | Taxed like a normal sell, with no referral discount. The collateral that covers the debt share is taken to repay it, untaxed. |
Errors and Recovery
Common Errors
| Error | Cause | Fix |
|---|---|---|
% by 10 / % range | Partial-sell percentage is not 10, 20 … 100 | Use a multiple of 10. |
incorrect loan duration | Days outside minDaysLoan..maxDaysLoan on a new loan or an extension | Use 10 to 1000 days today (read minDaysLoan() / maxDaysLoan()). |
Minimum loan amount not met | The collateral's value is under minimumLoan() | Add collateral. |
Open loan: increase it | takeLoan while you have an open loan on the same main and collateral token | Use increaseLoan() on that loan. |
Repay in full | A partial repay would leave less than minimumLoan() of debt | Repay more, or all. |
cannot sell off with no profit | A partial sell of a factory-token loan whose slice of collateral does not cover its slice of the debt | Repay instead, or wait for the collateral to gain value. |
wrong pair / Ecosystem inactive | The ecosystem argument is not the collateral's main, or the hub does not serve it | Pass the collateral's main (see Take a Loan). |
Duration too short | increaseLoan with 10 days or fewer left | Extend first. |
No borrowing power | increaseLoan adds no value above the debt | Add more collateral. |
Pay in stable or refinance, not both | extendLoan(…, true, true) | Pick one. |
Must be refinance if not extending time / Time remaining too short | 0 days without refinance, or a 0-day refinance with fewer than 10 days left | Add days. |
No equity / Minimum surplus not met / Fees exceed surplus value | A refinance with nothing, or too little, to borrow | Wait for the collateral to gain value. |
Not enough collateral to cover fees | payInStable = false and the debt plus fee reaches the collateral's value | Pay the fee in the pair asset. |
Core loan inactive / Loan not active | Repay or extend on a loan that was repaid or liquidated | Read getUserLoanDetails. |
Loan is still active / Nothing to claim | claimLiquidation() before a keeper liquidated the loan, or with nothing left | Wait for the keeper's liquidation; read isLiquidated. |
Invalid loan / Loan does not exist | A hub id that is not yours, or id 0 | Ids run from 1 to getUserLoanCount(wallet). |
Position active. Use addToLoan | vault.borrow() with a vault loan open | Use addToLoan() instead: see Module 06. |
Stable transfer failed, or the pair asset's own ERC-20 error | Not enough pair asset, or no allowance, to repay fullAmount | Top up the pair asset, then repay. |
For the full alphabetical error index across all modules, see Module 18: SDK Reference.
Recovery Flow: "Duration too short" on increaseLoan
If increaseLoan() fails because 10 days or fewer remain:
const details = await client.loans.getUserLoanDetails(walletAddress, hubId);
const now = Math.floor(Date.now() / 1000);
const remainingDays = Math.floor((Number(details.liquidationTime) - now) / 86400);
if (remainingDays <= 10) {
// an extension adds at least minDaysLoan (10) days; fewer reverts 'incorrect loan duration'
await client.loans.extendLoan(hubId, 10n, true, false);
}
// Now safe to add collateral
await client.loans.increaseLoan(hubId, additionalAmount);
Recovery Flow: "Position active. Use addToLoan"
If vault.borrow() reverts because you already have an active vault loan:
// Check for an existing vault loan before attempting to borrow
const vault = client.vault();
const pos = await vault.getPosition(walletAddress); // positions(main, user)
if (pos.hub !== zeroAddress) { // a vault loan is open
// Already has a loan: pledge more instead
await vault.addToLoan(additionalStasisAmount);
// To extend duration:
await vault.extendLoan(additionalDays, true, false);
} else {
// No active loan: safe to borrow
await vault.borrow(stasisAmount, 10n);
}
Common Mistakes
- Treating the 2% fee as an annual rate. It is a flat origination fee. A 365-day loan costs 3.825% total, not 730%.
- Taking long loans "to be safe." Interest is prepaid. If you repay on day 5 of a 90-day loan, you forfeit 85 days of prepaid interest. Always take 10 days and extend.
- Re-originating instead of extending. Each new loan costs 2% flat. An extension costs 0.005%/day. Extending 100 days = 0.5% vs. new loan = 2.5%.
- Using non-multiple-of-10 on partial sell. 25%, 33%, 50.5% will all revert
% by 10. Only use clean multiples: 10, 20, 30 ... 100. - Forgetting to claim after a liquidation. Surplus collateral (after the keeper's liquidation, less the 10% fee) is yours through
claimLiquidation(). It does not auto-return. Claim within 365 days of the liquidation; after that the leftover may no longer be claimable. - Calling
borrow()twice on a vault loan. Only one vault loan per wallet per main. UseaddToLoan()for additional collateral.
What Next
With the borrowed pair asset in hand, your options:
- Trading: Buy tokens with the borrowed pair asset. Your collateral and your new position can both appreciate, or both fall.
- Staking: Full vault loan walkthrough: stake → borrow. The pledged stake keeps earning rewards while borrowed against.
- Token Creation: Create a Floor+ or Predict+ token. Deploy the borrowed pair asset as the creation capital.
- Predictions: Buy outcome shares with the borrowed pair asset. Your token collateral can gain from volume, and a winning bet pays out on resolution.
- Vesting: Borrow against a vesting position with
takeLoanOnVesting()(same fee model, same expiry rules). - Strategy & Stacking: Full multi-position stacking: how to chain loans across paths for capital efficiency.
See Also
- Module 04: Trading: Spend the borrowed pair asset or close leverage positions (different system!)
- Module 06: Staking: Vault loans where the pledged stake keeps earning rewards
- Module 09: Vesting: Take loans against locked vesting positions
- Module 11: Token Mechanics: Floor math, Stable+ ratchet, hybrid multiplier
- Module 12: Strategy & Stacking: Multi-loan chaining for capital efficiency
- Module 18: SDK Reference: All
client.loansmethod signatures and full error index