A ledger-backed test-balance pool: supply, borrow USDT against BTC or ETH, repay, and inspect server-enforced liquidation rules. The live controls are followed by the mechanism and its production boundaries.
Sign in to supply test balances, borrow USDT against BTC or ETH, repay debt and inspect the same liquidation rules the server enforces. No balance here has monetary value and no return is promised.
Sign in to use the labEvery unit of interest a supplier receives here is paid by a borrower in the same balanced repayment or liquidation. There is no other source. A lending market has no yield-bearing asset in it, no fund manager, no strategy — it is a queue of people who want capital, a queue of people who have it, and a rule for pricing the gap.
That is why the live card derives its percentage from recorded pool supply and open principal instead of borrowing a market average. Below is the whole mechanism — how the rate forms, what backs the loan, and where this simulator stops.
A lending rate is only as good as the people paying it. These are the four kinds of borrower that fill an exchange loan book in practice — none of them borrows to spend it, and all of them are running a trade whose failure is what a lender is actually exposed to.
| Borrower | Borrows | To do what | What the lender is exposed to |
|---|---|---|---|
| Leveraged buyer | The quote asset | Hold a position larger than their own capital, without selling what they already own. | A fall in the collateral that outruns the sale of it. This is the common case and the one the whole safety system is built around. |
| Short seller | The asset itself | Sell it now and buy it back cheaper later, returning the same number of units. | A rise in the borrowed asset. The debt grows in the same move that stresses the collateral, so both sides of the loan degrade at once. |
| Market maker | Inventory, both sides | Quote a two-sided book without pre-funding every venue they trade on out of their own balance sheet. | Very little in normal conditions — this is the highest-quality demand in any loan book. In a dislocation it concentrates instantly into whichever name is moving. |
| Basis trader | The quote asset |
One hour of interest, and the only two places it can go. Nothing enters this picture from a treasury, a token emission or a marketing budget, because in a lending market nothing does.
Two consequences fall straight out of that drawing. A pool sitting idle pays its lenders nothing, because nobody is being charged. And a lender’s rate can never equal the borrower’s rate — the gap between them is utilisation and the reserve, and it never closes.
Utilisation is the share of a pool that is currently lent out. It is the only input a floating rate needs, and it does two jobs at once: it prices the loan, and it defends the lender’s ability to leave.
Both are called lending and they are not the same trade. The difference is not the rate — it is who carries the risk that the rate moves, and whether you can leave.
| Property compared | Floating — a pool | Fixed — a term loan |
|---|---|---|
| How the rate is set | Recomputed from utilisation on every accrual. It is a measurement of the pool, not a quote. | Agreed once, at origination, between two parties who have both decided the term is worth it. |
| When it changes | Continuously, without notice, in both directions. | Never. That is the entire product. |
| Getting your money back | Whenever the pool has idle capital — which is exactly when you are least likely to want out. | On the maturity date. Not before, at any price. |
| What you are exposed to | The rate collapsing when borrowing demand dries up, and the pool being fully drawn when you want to leave. | The rate rising while you are locked in, and the borrower's credit for the whole term rather than hour by hour. |
| Who uses it | Anyone with an idle balance and no view on how long they will hold it. |
Supply, borrowing, repayment and bounded liquidation all use the accounting substrate that already carries spot fills, perpetual margin and settlement. These are the current primitives, named as they are named in the source.
| Primitive | What it does today | How lending uses it |
|---|---|---|
| postTransfer | The single write path to the entry table. Refuses any set of legs that does not sum to zero per asset, and throws rather than reporting a validation error — an unbalanced transfer is a caller bug. | Every supply, withdrawal, draw, repayment, collateral release and liquidation. Lending adds no unbalanced way to move money. |
| Balances as a SUM | No balance is ever stored. Every figure is summed over ledger entries at read time, so a balance cannot silently disagree with its own history. |
Four pieces now work together in the test ledger. The final column names the remaining production gap so a bounded simulator is never presented as custody, execution or a real return.
| Component | What works now | Deliberate boundary |
|---|---|---|
Pool and supplier claims | USDT supply and withdrawals are balanced available ↔ lending transfers. Pool supply is the exact SUM of customer claims; open principal is the exact borrowed side. |
|
| Buy spot and sell the perpetual against it, collecting funding while carrying no net price exposure. |
| A trade that is market-neutral is not liquidity-neutral. The perpetual leg's margin call arrives on its own schedule, and the spot leg cannot always be sold fast enough to meet it. |
Note what is absent: nobody in that table is borrowing against future income, and there is no underwriting. Crypto lending is collateral-only, which makes it simpler than consumer credit and much more sensitive to the price of one asset.
The curve rises gently. Borrowing is cheap because capital is plentiful, and the pool is doing exactly what it is for. A lender who wants their money back gets it immediately, because most of the pool is sitting there.
The second slope is deliberately violent. It is not trying to price the loan fairly any more — it is trying to make borrowing painful enough that someone repays, and lending attractive enough that someone supplies, before the pool reaches the point where no lender can withdraw at all.
The number that matters most is the one at the right-hand edge. At full utilisation every unit in the pool is out on loan. A lender’s claim is still perfectly good and there is still nothing to pay it with — withdrawals are met from idle capital, and there is none. That is not a default; it is a queue. But it is the risk most often described as “withdraw at any time”, and the honest phrasing is at any time the pool has liquidity.
| Desks that need to know their funding cost in advance, because their own trade is priced off it. |
The two also fail differently. A floating pool degrades gradually — the rate moves, withdrawals slow. A term book fails all at once on a maturity date, which is why term lenders care about the borrower and pool lenders care about the collateral.
The formulas above are worth exactly nothing until someone runs a number through them. So here is one hour of interest, computed by this repository’s own decimal helpers rather than typed in as a literal.
The two marked figures are made up. They are not the lab’s current curve or reserve factor. They predate the interactive policy and remain only so this separate hourly example has round numbers. Use the live card above for server-derived rates; read this section as method, never as an indication of return.
Simple interest, no intra-year compounding: 750 × 8% ÷ 8760 hours = 0.00684932 USDT. This teaching model rounds the charge up. The bounded live simulator instead rounds simple interest down at ledger precision and discloses that policy; the two must not be mixed.
The reserve takes its share — also rounded up, also in the pool’s favour. What reaches the lender is the remainder, 0.00616438 USDT, never an independently computed figure. Rounding the lender’s side on its own formula is how a pool ends up paying out slightly more than it took in.
Twenty-four unchanged hours pay 0.14794512 USDT. Annualised, that hourly line implies 5.39999688% — against the textbook identity of 5.4%, which is borrow rate × utilisation × (1 − reserve factor). The gap is the two roundings, and it lands in the pool’s favour by construction rather than by accident.
Not “add interest to a balance”. A production scheduled accrual would be a balanced transfer. This bounded lab accrues debt deterministically on reads and interactions, then credits suppliers only when that interest is actually paid; its ledger transfer still has to sum to zero in every asset it touches.
| Ledger account | Bucket | Amount (USDT) |
|---|---|---|
| Borrowerthe loan, charged for the hour | available | −0.00684932 |
| Pool reservea system account, no trading account behind it | fees | +0.00068494 |
| Lenderthe remainder, never a separately rounded figure | available | +0.00616438 |
| Residual — what assertBalanced checks | 0 | |
The residual is added up at render time from the three legs above, not typed in. If the constants ever drifted out of balance this table would print the difference instead of a zero — which is the same guarantee assertBalanced gives the engine, applied to a page.
Nobody is underwritten. A crypto loan is secured by an asset worth more than the debt, and the entire safety system is one rule: sell the collateral before it is worth less than what is owed.
A borrower posts more value than they draw. The excess is not the lender’s profit — it is the room the system needs to sell into a falling market and still come out whole. How much room is a per-asset judgement about volatility and how deep the book is that would have to absorb the sale.
Closing a position early only works if the close completes. In a fast market the sale walks down a thinning book, and the price that triggered the liquidation is not the price it fills at. When the proceeds fall short, the difference is bad debt, and somebody owns it.
The lending simulator checks a fresh server-side spot mark, derives LTV from the loan’s stored debt and collateral, and closes an eligible loan in one balanced transaction. It repays debt, applies the published penalty, credits supplier interest and returns any remaining USDT.
It deliberately settles at that mark, not by walking the order book, and refuses a mark whose net proceeds would leave bad debt. That makes the boundary testable without pretending it is production execution. A real-money venue still needs slippage-aware sale routing, an insurance or loss waterfall, continuous monitoring and an operator path for insolvent loans.
| A supplier's claim is the SUM of its lending-bucket entries. Paid borrower interest is another immutable credit to that claim. |
| available · lending · lending_collateral | Available is spendable; lending and lending_collateral are customer-owned but deliberately excluded from order, transfer and withdrawal spend checks. All three remain visible in account valuation. | Supply moves available to lending. Opening a loan moves BTC or ETH into lending_collateral; full repayment reverses that collateral movement. |
| System accounts | A leg with no trading account behind it addresses the system side — external issuance and the fee account are explicit counterparties rather than hidden balance mutations. | A USDT draw is issued against external; repayment returns principal there. Supplier interest comes from the borrower, never from an invented yield account. |
| spot · futures · funding wallets | Three wallets per user, with transfers between them that lock both endpoints in canonical order and settle as one balanced transfer. | The spot wallet is the source and destination for supply, borrowed USDT, repayment and released collateral. |
| Idempotency keys | Every transfer carries a key derived from the operation, never from the clock. A replay returns the existing transfer and moves no money. | Client keys replay the exact supply, draw and repayment receipt; liquidation has one immutable receipt per loan. |
| Row locks before a spend | A balance is a SUM, and SELECT SUM takes no locks — so the ledger account row is locked FOR UPDATE before any balance that is about to be spent is read. | One global USDT pool lock serializes membership, draws and debt changes; wallet and collateral rows are locked before spend. |
| Recurring charges against a position | Funding already charges open perpetual positions every eight hours, taking payment from available first and the position's margin only for the remainder, and liquidating in the same transaction when the charge would exhaust it. | Each interaction settles elapsed debt at the stored prior-interval rate before publishing the new utilization rate. Paid interest moves only on repayment or liquidation. |
Rounding discipline comes with it: quantities round down, fees round up, and the direction is an explicit argument at every call site rather than a default someone might forget. An interest accrual inherits that on the day it is written.
| A published two-slope curve derives borrow APR from USDT utilization and supply APR from paid borrower demand. Each elapsed interval uses the rate stored when it began. |
|
Collateral and liquidation | One USDT loan per account, BTC/ETH collateral, max and maintenance LTV, fresh server marks, interest-first repayment, full collateral release and immutable liquidation receipts. |
|
Interaction accrual | Borrow, repay and liquidation settle every open loan to one deterministic event time using its stored prior rate, then publish the post-mutation rate. Reads estimate the same elapsed debt without writing. |
|
Supplying to a lending market is not a savings account and does not behave like one. These are the real loss paths, in roughly the order they occur in practice. The lab has no monetary value, but exposing the mechanics without their failure modes would still teach the wrong lesson.
The primary way. A market gaps through the liquidation threshold, the sale of the collateral fetches less than the debt, and the difference is a hole in the pool. The reserve absorbs it first; past the reserve it lands on lenders, usually as a quiet reduction in what each supplied unit is worth rather than as an announcement. This simulator refuses that insolvent path and moves nothing; it does not claim that refusal solves the production loss.
This lab uses a stricter, explicit term rule: USDT supplier membership cannot change while any pool loan is open. The claim stays visible in portfolio value but cannot be withdrawn until every loan settles. Production pools commonly allow exits only from idle liquidity and can still queue them at high utilization.
A floating rate is a measurement. If borrowing demand disappears — and it disappears fastest in quiet markets, when leverage is unwanted — the rate falls with it. Capital supplied at an attractive rate can sit earning almost nothing while the opportunity to deploy it elsewhere passes.
Every liquidation depends on a price, and a price is a claim about a market. A stale feed, a thin book or a single-print wick can each make collateral look adequate when it is not, or trigger a sale that should not have happened. This is why a mark price is built from an index rather than a last trade — and why the choice of feed is a risk parameter, not plumbing.
A loan book full of leveraged buyers is one trade wearing many names. The diversification a lender thinks they have across borrowers is often no diversification at all, and every loan deteriorates in the same hour.
The threshold, the reserve factor, the eligible collateral and the rate curve are all decisions made by an operator. A lender is taking a view on those decisions as much as on the borrowers, and is usually not shown them.
The live controls move only test-ledger balances with no monetary value, so they cannot create a real-world investment loss. They can lock simulated USDT for an open-loan term, accrue simulated debt and liquidate simulated collateral under the published rules. How this product works.
Deliberate boundary
It is a functioning test-ledger workflow, not a production lending product. It does not custody real assets, promise a return, run a continuous accrual or risk worker, execute collateral through an order book, or allocate an insolvent loss.