Skip to content

Commit 7c0f710

Browse files
author
Edward (OpenClaw)
committed
docs(asset-leasing): strip section numbers from headings; rewrite cross-references with word-based link text
WHAT: removed leading section numbers (1., 2., 3.1, 3.6, 3.8.1, etc.) from every heading in defi/asset-leasing/anchor/README.md. Updated the table of contents to point to the new numberless anchor slugs. Rewrote every cross-reference (previously written as [§3.6](...) or [Section 4 (...)](...)) to use word-based link text drawn from the heading itself, so the link reads as part of the surrounding prose. WHY: clickable links should read naturally inside a sentence rather than interrupt the reader with section-number references. Headings with leading numbers also drift out of sync the moment a section is reordered or renamed.
1 parent db46658 commit 7c0f710

1 file changed

Lines changed: 41 additions & 41 deletions

File tree

defi/asset-leasing/anchor/README.md

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,23 @@ anyway (think exchange-traded funds, pension funds, or any passive
1717
allocator), and short sellers and arbitrageurs get the tokens they
1818
need to sell short. The program is written in
1919
[Anchor](https://solana.com/docs/terminology); a parallel
20-
[Quasar port](#6-quasar-port) implements the same onchain behaviour.
20+
[Quasar port](#quasar-port) implements the same onchain behaviour.
2121

2222
---
2323

2424
## Table of contents
2525

26-
1. [What does this program do?](#1-what-does-this-program-do)
27-
2. [Accounts and program-derived addresses](#2-accounts-and-program-derived-addresses)
28-
3. [Lifecycle](#3-lifecycle)
29-
4. [Safety and edge cases](#4-safety-and-edge-cases)
30-
5. [Running the tests](#5-running-the-tests)
31-
6. [Quasar port](#6-quasar-port)
32-
7. [Extending the program](#7-extending-the-program)
26+
1. [What does this program do?](#what-does-this-program-do)
27+
2. [Accounts and program-derived addresses](#accounts-and-program-derived-addresses)
28+
3. [Lifecycle](#lifecycle)
29+
4. [Safety and edge cases](#safety-and-edge-cases)
30+
5. [Running the tests](#running-the-tests)
31+
6. [Quasar port](#quasar-port)
32+
7. [Extending the program](#extending-the-program)
3333

3434
---
3535

36-
## 1. What does this program do?
36+
## What does this program do?
3737

3838
A **holder** offers some quantity of **token A** - the leased token -
3939
for a fixed term. A **short seller** posts collateral in a different
@@ -165,7 +165,7 @@ rallies against the collateral. A drop in the borrowed asset price is
165165
purely beneficial to the short seller. The streaming lending fee is
166166
the position's only ongoing cost in either direction.
167167

168-
[Section 3 (Lifecycle)](#3-lifecycle) walks each instruction handler
168+
The [lifecycle](#lifecycle) section walks each instruction handler
169169
with concrete numbers that match the LiteSVM tests; the xNVDA example
170170
above is the same machinery applied to a real asset pair.
171171

@@ -176,11 +176,11 @@ above is the same machinery applied to a real asset pair.
176176
inline in `liquidate.rs`. Production code would depend on the
177177
`pyth-solana-receiver-sdk` crate so layout changes are caught at
178178
compile time.
179-
- See [Section 4 (Safety and edge cases)](#4-safety-and-edge-cases) for the rest of the deliberate simplifications.
179+
- See [safety and edge cases](#safety-and-edge-cases) for the rest of the deliberate simplifications.
180180

181181
---
182182

183-
## 2. Accounts and program-derived addresses
183+
## Accounts and program-derived addresses
184184

185185
Every call to the program touches some subset of these accounts. The
186186
three [program-derived addresses](https://solana.com/docs/terminology)
@@ -254,7 +254,7 @@ record the terminal state, but the account disappears at the end.
254254

255255
---
256256

257-
## 3. Lifecycle
257+
## Lifecycle
258258

259259
### What the short seller really gets
260260

@@ -275,9 +275,9 @@ the cost of fulfilling the obligation later is fixed in tokens whose
275275
price is unknown. Bet correctly on the direction and that asymmetry
276276
prints money. Bet wrong and the cost of buying the tokens back can
277277
exceed the cash plus the collateral, at which point the keepers
278-
arrive (see [§3.6](#36-branch-position-underwater---liquidate)).
278+
arrive (see [branch: position underwater - `liquidate`](#branch-position-underwater---liquidate)).
279279

280-
### 3.1 The holder lists the tokens - `create_lease`
280+
### The holder lists the tokens - `create_lease`
281281

282282
The holder calls `create_lease`, naming the leased mint, the
283283
collateral mint, the amount of leased tokens to offer, the
@@ -318,7 +318,7 @@ transfers to the program the moment the lease is listed.
318318
- `InvalidMaintenanceMargin` if `maintenance_margin_basis_points` is `0` or `> 50_000`
319319
- `InvalidLiquidationBounty` if `liquidation_bounty_basis_points > 2_000`
320320

321-
### 3.2 The short seller takes the offer - `take_lease`
321+
### The short seller takes the offer - `take_lease`
322322

323323
A short seller who has spotted the `Lease` account onchain (via an
324324
indexer or a direct lookup) calls `take_lease` to take delivery. The
@@ -357,7 +357,7 @@ moves from `Listed` to `Active`.
357357
`collateral_mint` do not match the values stored on the lease
358358
- `MathOverflow` if `now + duration_seconds` overflows `i64`
359359

360-
### 3.3 The lease fee streams - `pay_lease_fee`
360+
### The lease fee streams - `pay_lease_fee`
361361

362362
The lease fee accrues second by second out of the collateral vault.
363363
Anyone can call `pay_lease_fee` to settle whatever has accrued since
@@ -388,13 +388,13 @@ being liquidated, or defaulting; no further lease fees are owed.
388388
- If the vault did not have enough collateral to cover the full
389389
`lease_fee_due`, the residual is silently left as a debt the next
390390
`liquidate` or `close_expired` call cleans up. (See
391-
[Section 4 (Safety and edge cases)](#4-safety-and-edge-cases) for
391+
[safety and edge cases](#safety-and-edge-cases) for
392392
the rationale on this trade-off.)
393393
- **Errors:**
394394
- `InvalidLeaseStatus` if the lease is not `Active`
395395
- `MathOverflow` if `elapsed * lease_fee_per_second` overflows `u64`
396396

397-
### 3.4 The short seller defends the position - `top_up_collateral`
397+
### The short seller defends the position - `top_up_collateral`
398398

399399
If the price moves against the short seller and the position drifts
400400
toward the maintenance-margin floor, the short seller can add more
@@ -423,7 +423,7 @@ is `Active`.
423423
- `InvalidLeaseStatus` if the lease is not `Active`
424424
- `MathOverflow` if the addition overflows `u64`
425425

426-
### 3.5 The short seller closes - `return_lease`
426+
### The short seller closes - `return_lease`
427427

428428
To close the position, the short seller buys back the leased tokens
429429
on the open market and calls `return_lease`. The program runs the
@@ -476,7 +476,7 @@ time at `end_timestamp`.
476476
- `Unauthorised` if `lease.short_seller != short_seller.key()`
477477
- `MathOverflow` if the lease-fee or collateral subtraction overflows
478478

479-
### 3.6 Branch: position underwater - `liquidate`
479+
### Branch: position underwater - `liquidate`
480480

481481
If the leased asset rallies far enough that the locked collateral is
482482
no longer worth more than the debt times the maintenance margin,
@@ -545,7 +545,7 @@ math non-negative (see [`is_underwater`](programs/asset-leasing/src/instructions
545545
- `InvalidLeaseStatus` if the lease is not `Active`
546546
- `MathOverflow` on any of the integer-multiplication steps
547547

548-
### 3.7 Branch: cancel or default - `close_expired`
548+
### Branch: cancel or default - `close_expired`
549549

550550
The holder has a single recovery handler that covers two unrelated
551551
situations:
@@ -591,7 +591,7 @@ rent-exempt-lamport refunds going to the holder.
591591
- `InvalidLeaseStatus` if `status` is not `Listed` or `Active`
592592
- `LeaseNotExpired` if `status == Active` and `now < end_timestamp`
593593

594-
### 3.8 Branch scenarios
594+
### Branch scenarios
595595

596596
The handlers above cover the happy path. The branch scenarios below
597597
walk the same machinery through liquidation, a falling-price profit,
@@ -615,9 +615,9 @@ Shared starting parameters:
615615
The holder starts with 1 000 000 000 leased units; the short seller
616616
starts with 1 000 000 000 collateral units. Each scenario opens with
617617
`create_lease` and (where relevant) `take_lease` running as described
618-
in [§3.1](#31-the-holder-lists-the-tokens---create_lease) and [§3.2](#32-the-short-seller-takes-the-offer---take_lease). Lease fees use the formula in [§3.3](#33-the-lease-fee-streams---pay_lease_fee).
618+
in [the holder lists the tokens - `create_lease`](#the-holder-lists-the-tokens---create_lease) and [the short seller takes the offer - `take_lease`](#the-short-seller-takes-the-offer---take_lease). Lease fees use the formula in [the lease fee streams - `pay_lease_fee`](#the-lease-fee-streams---pay_lease_fee).
619619

620-
#### 3.8.1 Liquidation - leased asset rallies
620+
#### Liquidation - leased asset rallies
621621

622622
`create_lease` and `take_lease` run as standard, leaving
623623
`collateral_vault = 200_000_000`, `leased_vault = 0`, and the short
@@ -630,7 +630,7 @@ pot of ~200 000 000 - maintenance ratio is `200/400 = 50%`, far below
630630
the required 120%. The keeper does not need to call `pay_lease_fee`
631631
first; `liquidate` settles accrued fees itself.
632632

633-
The keeper calls `liquidate` (mechanics in [§3.6](#36-branch-position-underwater---liquidate)). At `T + 300`:
633+
The keeper calls `liquidate` (mechanics in [branch: position underwater - `liquidate`](#branch-position-underwater---liquidate)). At `T + 300`:
634634

635635
- Accrued lease fee: `300 × 10 = 3_000` collateral units. The vault
636636
has 200 000 000, so `lease_fee_payable = 3_000` flows to the holder.
@@ -655,7 +655,7 @@ The asymmetry to remember: liquidation does *not* reclaim the leased
655655
tokens. The collateral pays the holder for the lost asset; the short
656656
seller has effectively bought the leased tokens at the forfeit price.
657657

658-
#### 3.8.2 Falling price - short seller profits
658+
#### Falling price - short seller profits
659659

660660
`create_lease` and `take_lease` run as standard. Time jumps to
661661
`T + 300`. The leased-in-collateral price has fallen sharply: take
@@ -669,7 +669,7 @@ a healthy position.
669669
At `T + 600` (10 minutes in) the short seller buys 100 leased tokens
670670
on the open market at the new price (about 50 collateral tokens
671671
total - far less than the 200 they posted) and calls `return_lease`
672-
(mechanics in [§3.5](#35-the-short-seller-closes---return_lease)). Accrued lease fees are `600 × 10 = 6_000`
672+
(mechanics in [the short seller closes - `return_lease`](#the-short-seller-closes---return_lease)). Accrued lease fees are `600 × 10 = 6_000`
673673
collateral units. The settlement:
674674

675675
- 100 000 000 leased units flow short seller → leased vault → holder.
@@ -690,18 +690,18 @@ Final balances:
690690
payoff.
691691

692692
The short seller can defend a borderline position with
693-
`top_up_collateral` ([§3.4](#34-the-short-seller-defends-the-position---top_up_collateral)) or close it early via `return_lease`
694-
([§3.5](#35-the-short-seller-closes---return_lease)). Only adverse price moves trigger liquidation.
693+
`top_up_collateral` ([the short seller defends the position - `top_up_collateral`](#the-short-seller-defends-the-position---top_up_collateral)) or close it early via `return_lease`
694+
([the short seller closes - `return_lease`](#the-short-seller-closes---return_lease)). Only adverse price moves trigger liquidation.
695695

696-
#### 3.8.3 Default - `close_expired` on an `Active` lease
696+
#### Default - `close_expired` on an `Active` lease
697697

698698
`create_lease` and `take_lease` run as standard. The short seller
699699
takes the tokens, posts collateral, then disappears. `pay_lease_fee`
700700
is never called. The clock advances past
701701
`end_timestamp = T + 86_400`.
702702

703703
At `T + 100_000` the holder calls `close_expired` (mechanics in
704-
[§3.7](#37-branch-cancel-or-default---close_expired)). Because `status == Active` and `now >= end_timestamp`, the
704+
[branch: cancel or default - `close_expired`](#branch-cancel-or-default---close_expired)). Because `status == Active` and `now >= end_timestamp`, the
705705
default branch runs:
706706

707707
- `leased_vault` is empty (the short seller kept the tokens) - no
@@ -719,11 +719,11 @@ Final balances:
719719
- **Short seller:** 100 000 000 leased units, paid the full
720720
collateral and kept the leased tokens.
721721

722-
#### 3.8.4 Cancel - `close_expired` on a `Listed` lease
722+
#### Cancel - `close_expired` on a `Listed` lease
723723

724724
The cheap cancel path. `create_lease` runs; no short seller ever
725725
calls `take_lease`. The holder calls `close_expired` immediately
726-
(mechanics in [§3.7](#37-branch-cancel-or-default---close_expired)). Because `status == Listed`, no expiry check
726+
(mechanics in [branch: cancel or default - `close_expired`](#branch-cancel-or-default---close_expired)). Because `status == Listed`, no expiry check
727727
applies:
728728

729729
- `leased_vault` holds 100 000 000 leased units; all of it drains
@@ -736,9 +736,9 @@ nothing else moved.
736736

737737
---
738738

739-
## 4. Safety and edge cases
739+
## Safety and edge cases
740740

741-
### 4.1 What the program refuses to do
741+
### What the program refuses to do
742742

743743
All of the following come from [`errors.rs`](programs/asset-leasing/src/errors.rs)
744744
and are enforced by either an Anchor constraint or a `require!` in the
@@ -761,7 +761,7 @@ handler:
761761
- **`LeasedMintEqualsCollateralMint`** - `create_lease` called with the same mint for both sides.
762762
- **`PriceFeedMismatch`** - `liquidate` called with a Pyth update whose `feed_id` does not match `lease.feed_id`.
763763

764-
### 4.2 Guarded design choices worth knowing
764+
### Guarded design choices worth knowing
765765

766766
- **Leased tokens are locked up-front.** `create_lease` moves the tokens
767767
into the `leased_vault` immediately, so a short seller calling
@@ -805,7 +805,7 @@ handler:
805805
cut would dwarf the holder's recovery on default. The cap keeps
806806
liquidation economics roughly in line with holder-first semantics.
807807

808-
### 4.3 Things the program does *not* guard against
808+
### Things the program does *not* guard against
809809

810810
A production version of the program would want more:
811811

@@ -847,7 +847,7 @@ A production version of the program would want more:
847847

848848
---
849849

850-
## 5. Running the tests
850+
## Running the tests
851851

852852
All the tests are LiteSVM-based Rust integration tests under
853853
[`programs/asset-leasing/tests/`](programs/asset-leasing/tests/). They
@@ -918,7 +918,7 @@ CI is already covered.
918918

919919
---
920920

921-
## 6. Quasar port
921+
## Quasar port
922922

923923
A parallel implementation of the same program using
924924
[Quasar](https://github.com/blueshift-gg/quasar) lives in
@@ -1019,7 +1019,7 @@ handler. Tests are in `src/tests.rs`.
10191019

10201020
---
10211021

1022-
## 7. Extending the program
1022+
## Extending the program
10231023

10241024
Directions a real-world version of the program would consider,
10251025
grouped by effort:

0 commit comments

Comments
 (0)