@logswap/sdk 0.5.55 → 0.5.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -75
- package/dist/actions.d.ts +1 -1
- package/dist/actions.js +1 -1
- package/dist/admin.d.ts +7 -7
- package/dist/admin.js +7 -7
- package/dist/client.d.ts +6 -6
- package/dist/client.js +16 -16
- package/dist/fpool.d.ts +53 -53
- package/dist/fpool.js +49 -49
- package/dist/keys.d.ts +1 -1
- package/dist/liquidity.d.ts +7 -7
- package/dist/liquidity.js +6 -6
- package/dist/pools.d.ts +2 -2
- package/dist/pools.js +1 -1
- package/package.json +3 -2
- package/src/actions.ts +1 -1
- package/src/admin.ts +8 -8
- package/src/client.ts +18 -18
- package/src/fpool.ts +66 -66
- package/src/keys.ts +1 -1
- package/src/liquidity.ts +8 -8
- package/src/pools.ts +2 -2
package/dist/fpool.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* The other primitive. `CPoolManager` gives every position its own floor on a tick ladder;
|
|
5
5
|
* `FPoolManager` gives every share the SAME floor and deletes the ladder, the accumulators and the
|
|
6
6
|
* per-position accounting with it. Reading the two side by side is the fastest way to understand
|
|
7
|
-
* either
|
|
7
|
+
* either.
|
|
8
8
|
*
|
|
9
9
|
* **A pool is an ID, not an address.** Both primitives are singletons now, so neither has a
|
|
10
10
|
* per-pool deployment — but they are addressed differently and for a reason. The C manager rides
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* **Two products, one contract.** The basket (n > 1) and the launch (n = 1, the creator alone on
|
|
16
16
|
* the lever) are the same bytecode under two key fields — the KIND (what the manager promises
|
|
17
17
|
* structurally) and the POLICY (the pool's policy: its roles, its gates, the terms of every harvest
|
|
18
|
-
* and release
|
|
18
|
+
* and release) — and nothing in the maths. `describeFPool` below reports
|
|
19
19
|
* which shape a given pool is, because a UI has to decide what to render.
|
|
20
20
|
*
|
|
21
21
|
* **The roles are the policy's, not the manager's** (F version 15). The manager holds no
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
import { encodeFunctionData, toFunctionSelector } from "viem";
|
|
33
33
|
import { fPoolManagerAbi, logswapRouterAbi, padPolicyAbi, polPolicyAbi, policyRegistryAbi, privatePolicyAbi, publicPolicyAbi } from "./generated.js";
|
|
34
34
|
/**
|
|
35
|
-
* One contract, one ABI (
|
|
35
|
+
* One contract, one ABI (F version 12): `harvest`, `claim`, `retire`, `regenerate`,
|
|
36
36
|
* `setLegs`, the names, the fee parameters are `FPoolManager`'s own code. The roles left it for
|
|
37
|
-
* the policies in F version 15
|
|
37
|
+
* the policies in F version 15: {@link fPolicyBaseAbi} is what every policy shares,
|
|
38
38
|
* {@link privatePolicyAbi} the desk's, {@link padPolicyAbi} / {@link polPolicyAbi} / {@link publicPolicyAbi}
|
|
39
39
|
* the kinds'.
|
|
40
40
|
*/
|
|
@@ -48,7 +48,7 @@ export const fPolicyBaseAbi = polPolicyAbi;
|
|
|
48
48
|
import { signerFor } from "./write.js";
|
|
49
49
|
const WAD = 10n ** 18n;
|
|
50
50
|
const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
51
|
-
/** The optional questions a policy declared at birth
|
|
51
|
+
/** The optional questions a policy declared at birth, as bits of `Pool.asks`. */
|
|
52
52
|
export const ASK_SWAP = 1;
|
|
53
53
|
export const ASK_MINT = 2;
|
|
54
54
|
/** Read a basket pool whole. Batched — viem multicalls these when the transport allows. */
|
|
@@ -75,8 +75,8 @@ export async function getFPool(c, poolId) {
|
|
|
75
75
|
const n = Number(p.n);
|
|
76
76
|
const idx = Array.from({ length: n }, (_, i) => BigInt(i));
|
|
77
77
|
const [theta, compositeX, legs, kind, name] = await Promise.all([
|
|
78
|
-
// before the seed there is no L and no floor: θ is X by convention (
|
|
79
|
-
//
|
|
78
|
+
// before the seed there is no L and no floor: θ is X by convention (older deployments revert
|
|
79
|
+
// with DivWadFailed, so do not ask them)
|
|
80
80
|
p.L > 0n ? rd("theta", [poolId]) : rd("compositeX", [poolId]),
|
|
81
81
|
rd("compositeX", [poolId]),
|
|
82
82
|
Promise.all(idx.map((i) => rd("legOf", [poolId, i]))),
|
|
@@ -85,7 +85,7 @@ export async function getFPool(c, poolId) {
|
|
|
85
85
|
]);
|
|
86
86
|
const bases = legs.map((l) => l[0]);
|
|
87
87
|
const weights = legs.map((l) => l[1]);
|
|
88
|
-
const x = legs.map((l) => l[2]); // derived by the manager: x_j = ln(w_j·L / R_j)
|
|
88
|
+
const x = legs.map((l) => l[2]); // derived by the manager: x_j = ln(w_j·L / R_j)
|
|
89
89
|
const reserves = legs.map((l) => l[3]); // the state
|
|
90
90
|
const { quote, Q, L, phi, theta0, bigSigma, policy, restructureBlock, seeded, gen } = p;
|
|
91
91
|
const totalSupply = p.shares;
|
|
@@ -119,7 +119,7 @@ export const SEED_TO_DEAD = 4;
|
|
|
119
119
|
const kindCache = new Map();
|
|
120
120
|
/**
|
|
121
121
|
* What a policy IS — its `kind()` tag, read once per policy address and cached for the client's
|
|
122
|
-
* chain: a pool's kind is its policy's word
|
|
122
|
+
* chain: a pool's kind is its policy's word, never the manager's. An unknown tag
|
|
123
123
|
* (a policy that is not one of the protocol's four shapes) throws; the app has no screen for it.
|
|
124
124
|
*/
|
|
125
125
|
export function fPoolKindOfPolicy(c, policy) {
|
|
@@ -137,13 +137,13 @@ export function fPoolKindOfPolicy(c, policy) {
|
|
|
137
137
|
}
|
|
138
138
|
return hit;
|
|
139
139
|
}
|
|
140
|
-
/** The pool's label, as its policy holds it
|
|
140
|
+
/** The pool's label, as its policy holds it. "" when unnamed. */
|
|
141
141
|
export async function fPoolNameOf(c, poolId, policy) {
|
|
142
142
|
const p = policy ?? (await fPoolPolicyOf(c, poolId));
|
|
143
143
|
const word = (await c.public.readContract({ address: p, abi: fPolicyBaseAbi, functionName: "nameOf", args: [poolId] }));
|
|
144
144
|
return bytes32ToText(word);
|
|
145
145
|
}
|
|
146
|
-
/** The deployment's policy for a kind
|
|
146
|
+
/** The deployment's policy for a kind: the protocol's policy that IS that kind. */
|
|
147
147
|
export function fPoolPolicyFor(c, kind) {
|
|
148
148
|
const a = c.addresses;
|
|
149
149
|
const policy = kind === "public" ? a.publicPolicy : kind === "private" ? a.privatePolicy : kind === "pol" ? a.polPolicy : a.padPolicy;
|
|
@@ -196,7 +196,7 @@ export async function describeFPool(c, s) {
|
|
|
196
196
|
? await Promise.all([rd("unharvested"), rd("harvestable"), rd("dividendOf", [s.poolId, BigInt(s.gen), DEAD_ADDRESS])])
|
|
197
197
|
: [0n, 0n, 0n];
|
|
198
198
|
return {
|
|
199
|
-
shape: s.kind === "pad" ? "launch" : "basket", // the kind, not n = 1
|
|
199
|
+
shape: s.kind === "pad" ? "launch" : "basket", // the kind, not n = 1
|
|
200
200
|
legs: s.bases.length,
|
|
201
201
|
atFloor: s.Q === 0n,
|
|
202
202
|
unharvested,
|
|
@@ -249,7 +249,7 @@ a) {
|
|
|
249
249
|
}
|
|
250
250
|
/**
|
|
251
251
|
* Burn shares for the pro-rata slice of every reserve. Available at any Q, and after dissolution.
|
|
252
|
-
* By owner
|
|
252
|
+
* By owner: the account burns its own shares; an
|
|
253
253
|
* operator may pass another owner's address, as on the C manager's `burnById`.
|
|
254
254
|
*/
|
|
255
255
|
export async function fPoolBurn(c,
|
|
@@ -294,7 +294,7 @@ export async function fPoolPreviewZapIn(c, poolId, dL) {
|
|
|
294
294
|
*
|
|
295
295
|
* The imbalanced part goes through the pool's own curve before anything is minted. That is not a
|
|
296
296
|
* penalty: minting against a quote-only deposit would be a zero-slippage, zero-fee swap at stale
|
|
297
|
-
* spot, paid for by the existing LPs
|
|
297
|
+
* spot, paid for by the existing LPs. Routing it through
|
|
298
298
|
* the curve deletes the subsidy and hands the fee and impact to the incumbents instead.
|
|
299
299
|
*/
|
|
300
300
|
export async function fPoolZapIn(c, a) {
|
|
@@ -331,7 +331,7 @@ export async function fPoolPreviewZapOut(c, a) {
|
|
|
331
331
|
return result;
|
|
332
332
|
}
|
|
333
333
|
/**
|
|
334
|
-
* Roll a retired generation's bundle into the pool's live one
|
|
334
|
+
* Roll a retired generation's bundle into the pool's live one, on the
|
|
335
335
|
* router under one lock: redeem `shares` of generation `gen` in place — the legs, the quote and
|
|
336
336
|
* any unpulled dividend come back — buy through the pool's own curve only what the live
|
|
337
337
|
* generation's ratio lacks, mint `dL` of it to `to`, and refund the rest in kind. Quote the
|
|
@@ -363,26 +363,26 @@ export async function fPoolPreviewRollIn(c, poolId, gen, holder, shares) {
|
|
|
363
363
|
}
|
|
364
364
|
// ─── the floor lever (authority only) ─────────────────────────────────────────
|
|
365
365
|
/**
|
|
366
|
-
* Remove quote, lifting θ — price-neutral, no base moves, and
|
|
366
|
+
* Remove quote, lifting θ — price-neutral, no base moves, and a DIVIDEND to
|
|
367
367
|
* every share: the amount goes into the pool's pot and each holder's slice is settled lazily on
|
|
368
368
|
* their next transfer, mint or burn, or pulled with {@link fPoolClaim}. The sponsor's own slice —
|
|
369
369
|
* its shares' and the locked seed's at 0xdead — is pushed to `to` at once. On a pad
|
|
370
|
-
* the lift stops at the seed floor θ₀ (income only); nothing else bounds it
|
|
370
|
+
* the lift stops at the seed floor θ₀ (income only); nothing else bounds it — an
|
|
371
371
|
* unlocked pool's authority may take Q to zero.
|
|
372
372
|
*/
|
|
373
373
|
export async function fPoolHarvest(c, a) {
|
|
374
374
|
return writeFPool(c, a.poolId, "harvest", [a.amount, a.to ?? a.account], a.account);
|
|
375
375
|
}
|
|
376
376
|
/**
|
|
377
|
-
* Pull one's settled dividend
|
|
377
|
+
* Pull one's settled dividend on a generation's shares without moving them;
|
|
378
378
|
* anyone with shares. `gen` defaults to the live generation; a retired generation's harvests
|
|
379
|
-
* stay claimable under its own id
|
|
379
|
+
* stay claimable under its own id.
|
|
380
380
|
*/
|
|
381
381
|
export async function fPoolClaim(c, a) {
|
|
382
382
|
const gen = a.gen ?? (await fPoolGen(c, a.poolId));
|
|
383
383
|
return writeFPool(c, a.poolId, "claim", [BigInt(gen), a.to ?? a.account], a.account);
|
|
384
384
|
}
|
|
385
|
-
/** A holder's dividend as of now on generation `gen` (the live one by default) — banked plus pending on the current balance
|
|
385
|
+
/** A holder's dividend as of now on generation `gen` (the live one by default) — banked plus pending on the current balance. */
|
|
386
386
|
export async function fPoolDividendOf(c, poolId, holder, gen) {
|
|
387
387
|
const g = gen ?? (await fPoolGen(c, poolId));
|
|
388
388
|
return c.public.readContract({
|
|
@@ -513,7 +513,7 @@ export async function approveRouterForFPool(c, account) {
|
|
|
513
513
|
// than read from the chain: it is pure, and a client that has to call to learn an id cannot build
|
|
514
514
|
// a multicall that uses it.
|
|
515
515
|
/**
|
|
516
|
-
* The ERC-6909 id carrying generation `gen` of a pool's shares
|
|
516
|
+
* The ERC-6909 id carrying generation `gen` of a pool's shares: bit 255 set (the
|
|
517
517
|
* share flag), the pool id's top 239 bits, the generation in the low 16. Each generation's shares
|
|
518
518
|
* are their own asset — a retired one is a claim on its bundle, the live one on the pool.
|
|
519
519
|
*/
|
|
@@ -548,7 +548,7 @@ export async function fPoolShareBalance(c, poolId, owner, gen) {
|
|
|
548
548
|
args: [owner, fPoolShareId(poolId, g)],
|
|
549
549
|
});
|
|
550
550
|
}
|
|
551
|
-
/** A retired generation's bundle
|
|
551
|
+
/** A retired generation's bundle: what is left to redeem — supply, quote, base per leg index. */
|
|
552
552
|
export async function fPoolBundleOf(c, poolId, gen) {
|
|
553
553
|
const [supply, quote, base] = (await c.public.readContract({
|
|
554
554
|
address: c.addresses.fPoolManager,
|
|
@@ -558,7 +558,7 @@ export async function fPoolBundleOf(c, poolId, gen) {
|
|
|
558
558
|
}));
|
|
559
559
|
return { supply, quote, base: [...base] };
|
|
560
560
|
}
|
|
561
|
-
/** A holder's claims on a pool's retired generations — one row per generation still held
|
|
561
|
+
/** A holder's claims on a pool's retired generations — one row per generation still held. */
|
|
562
562
|
export async function fPoolClaimsOf(c, poolId, owner) {
|
|
563
563
|
const { logswapLensAbi } = await import("./generated.js");
|
|
564
564
|
const rows = (await c.public.readContract({
|
|
@@ -570,7 +570,7 @@ export async function fPoolClaimsOf(c, poolId, owner) {
|
|
|
570
570
|
return rows.map((r) => ({ gen: Number(r.gen), shares: r.shares, base: [...r.base], quote: r.quote, dividend: r.dividend }));
|
|
571
571
|
}
|
|
572
572
|
/**
|
|
573
|
-
* Redeem `shares` of a RETIRED generation
|
|
573
|
+
* Redeem `shares` of a RETIRED generation: its bundle, pro rata — the base per
|
|
574
574
|
* leg and the quote — plus the owner's settled dividend. Not `burn`: nothing can move a bundle's
|
|
575
575
|
* ratio, so there is no slippage to bound. The owner, or an operator of theirs.
|
|
576
576
|
*/
|
|
@@ -708,8 +708,8 @@ export async function fPoolIdOf(c, a) {
|
|
|
708
708
|
});
|
|
709
709
|
}
|
|
710
710
|
/**
|
|
711
|
-
* The reserve a leg holds at a mark: `R = Lj·e^{−x}`, WAD math. The seed names RESERVES
|
|
712
|
-
*
|
|
711
|
+
* The reserve a leg holds at a mark: `R = Lj·e^{−x}`, WAD math. The seed names RESERVES —
|
|
712
|
+
* the sponsor states holdings and the price follows, `p = Lj / R` — so this is
|
|
713
713
|
* the one conversion from a price to what the pool will hold, done here, on the way in. Float
|
|
714
714
|
* precision (~1e-16 relative) is what a seed needs: any reserve is a legal seed, and the mark
|
|
715
715
|
* the pool derives from it is the one the sponsor meant to within that.
|
|
@@ -730,7 +730,7 @@ export async function fPoolSeed(c, a) {
|
|
|
730
730
|
return writeFPool(c, a.poolId, "seed", [a.L0, r0, a.Q0], a.account);
|
|
731
731
|
}
|
|
732
732
|
/**
|
|
733
|
-
* Retire the live generation
|
|
733
|
+
* Retire the live generation — the raw entry (`dissolve` before F
|
|
734
734
|
* version 14). Allowed only at an empty bid, Q ≤ L/1e9, on every pool: the market took it, or the
|
|
735
735
|
* operator harvested it out first ({@link fPoolRetire} does both in one transaction). The live
|
|
736
736
|
* (S, Q, R_j) become a frozen bundle every share of this generation redeems ({@link fPoolRedeem})
|
|
@@ -756,25 +756,25 @@ export async function fPoolRetire(c, a) {
|
|
|
756
756
|
}
|
|
757
757
|
/**
|
|
758
758
|
* The harvests that empty an unlocked pool's bid, in order — what a relaunch sends before its
|
|
759
|
-
* `retire` (
|
|
759
|
+
* `retire` (a retire needs an empty bid on every pool). Since F version 14 one
|
|
760
760
|
* `harvest(Q)` does it: the protocol's cut leaves the pool with the amount (with no collector
|
|
761
761
|
* there is no cut). `[]` when the bid is already empty. Throws on a pad that still bids (its bid
|
|
762
762
|
* empties only as the market sells it down), and when the pool's policy keeps a floor on the bid
|
|
763
|
-
* (`PolPolicy.keepQuote
|
|
763
|
+
* (`PolPolicy.keepQuote`): a `retire` under that policy waits for the market.
|
|
764
764
|
*/
|
|
765
765
|
export async function fPoolEmptyingHarvests(c, poolId) {
|
|
766
766
|
const s = await getFPool(c, poolId);
|
|
767
767
|
if (s.Q === 0n)
|
|
768
768
|
return [];
|
|
769
769
|
if (s.kind === "pad")
|
|
770
|
-
throw new Error("logswap: a pad is retired only once its bid is empty
|
|
770
|
+
throw new Error("logswap: a pad is retired only once its bid is empty");
|
|
771
771
|
const { maxHarvest } = await getFPoolRoles(c, poolId, s);
|
|
772
772
|
if (maxHarvest < s.Q)
|
|
773
|
-
throw new Error("logswap: the pool's policy keeps a floor on the bid — it cannot be harvested empty
|
|
773
|
+
throw new Error("logswap: the pool's policy keeps a floor on the bid — it cannot be harvested empty");
|
|
774
774
|
return [s.Q];
|
|
775
775
|
}
|
|
776
776
|
/**
|
|
777
|
-
* Release the dead shares' pot under the policy's terms
|
|
777
|
+
* Release the dead shares' pot under the policy's terms — a pad's graduation.
|
|
778
778
|
* The manager harvests the generation's income first (the pot then holds everything the dead
|
|
779
779
|
* shares earned), asks the policy, and applies its answer: a share to the payee it names (the pad's
|
|
780
780
|
* creator — the pool's authority), a cut to the collector, the rest bought in as more of the
|
|
@@ -785,7 +785,7 @@ export async function fPoolRegenerate(c, a) {
|
|
|
785
785
|
return writeFPool(c, a.poolId, "regenerate", [a.to ?? a.account], a.account);
|
|
786
786
|
}
|
|
787
787
|
/**
|
|
788
|
-
* The relaunch as ONE transaction
|
|
788
|
+
* The relaunch as ONE transaction: `harvest` the bid out — a
|
|
789
789
|
* dividend to every share, {@link fPoolEmptyingHarvests} — `retire` the live generation at the
|
|
790
790
|
* empty bid, `redeem` the caller's own shares of it (when `shares` > 0), optionally `setLegs` the
|
|
791
791
|
* next generation's composition (`legs`: a private pool's reshape — retire, admit, reweight), and
|
|
@@ -810,7 +810,7 @@ export async function fPoolRelaunch(c, a) {
|
|
|
810
810
|
];
|
|
811
811
|
return writeFPool0(c, "multicall", [calls], a.account);
|
|
812
812
|
}
|
|
813
|
-
/** Where a pad's seed lives
|
|
813
|
+
/** Where a pad's seed lives: `seed` mints every share of a pad here itself. */
|
|
814
814
|
export const DEAD_ADDRESS = "0x000000000000000000000000000000000000dEaD";
|
|
815
815
|
/** The manager's `MIN_SHARES`: the seed mints this much to 0xdead on every pool, the rest to the seeder — or, on a pad, to 0xdead too. */
|
|
816
816
|
export const F_MIN_SHARES = 1000n;
|
|
@@ -837,22 +837,22 @@ export function fPoolLaunchCalls(poolId, a) {
|
|
|
837
837
|
calls.push(enc("initialize", [key]));
|
|
838
838
|
calls.push(enc("seed", [poolId, a.L0, companions[1], a.Q0]));
|
|
839
839
|
// gen 0 by construction: a launch is the pool's FIRST seed — a relaunch is `fPoolRelaunch`.
|
|
840
|
-
// No transfer to 0xdead: on a pad `seed` mints every share there itself
|
|
840
|
+
// No transfer to 0xdead: on a pad `seed` mints every share there itself.
|
|
841
841
|
if (a.openBuy) {
|
|
842
842
|
const j = bases.indexOf(a.bases[a.openBuy.j]);
|
|
843
843
|
if (j < 0)
|
|
844
844
|
throw new Error(`logswap: openBuy.j = ${a.openBuy.j} is not a leg`);
|
|
845
845
|
calls.push(enc("swapQuoteIn", [poolId, BigInt(j), a.openBuy.amountIn, a.openBuy.minOut ?? 0n, a.account]));
|
|
846
846
|
}
|
|
847
|
-
// the name, the desk's gates and its list are the POLICY's
|
|
847
|
+
// the name, the desk's gates and its list are the POLICY's, not the
|
|
848
848
|
// manager's: they cannot ride in this batch — `fPoolLaunch` and `fPoolDeskOpening` send them
|
|
849
849
|
// right after, as the same creator
|
|
850
850
|
calls.push(...(a.extra ?? []));
|
|
851
851
|
return calls;
|
|
852
852
|
}
|
|
853
853
|
/**
|
|
854
|
-
* The desk's opening posture, on its policy
|
|
855
|
-
* minter. No appointment: the authority is the operator until one is appointed
|
|
854
|
+
* The desk's opening posture, on its policy: gated minting, the creator a
|
|
855
|
+
* minter. No appointment: the authority is the operator until one is appointed.
|
|
856
856
|
* Two writes to `PrivatePolicy`; the launch batch cannot carry them (they are not manager calls).
|
|
857
857
|
*/
|
|
858
858
|
export async function fPoolDeskOpening(c, a) {
|
|
@@ -888,7 +888,7 @@ export async function fPoolLaunch(c, a) {
|
|
|
888
888
|
await fPoolSetName(c, { poolId, name: a.name, account: a.account, policy });
|
|
889
889
|
return { hash, poolId };
|
|
890
890
|
}
|
|
891
|
-
// ─── the roles, on the policy
|
|
891
|
+
// ─── the roles, on the policy ─────────────────────────────────────────────
|
|
892
892
|
//
|
|
893
893
|
// Every write here goes to the pool's POLICY, not the manager: the manager holds no role. `policy`
|
|
894
894
|
// may be passed when in hand (`FPoolState.policy`, `FPoolRoles.policy`); otherwise it is read once.
|
|
@@ -906,7 +906,7 @@ async function writePolicy(c, abi, a, functionName, args) {
|
|
|
906
906
|
return wallet.writeContract(request);
|
|
907
907
|
}
|
|
908
908
|
/**
|
|
909
|
-
* Propose the next authority — step one of two
|
|
909
|
+
* Propose the next authority — step one of two, on the pool's policy. Nothing moves
|
|
910
910
|
* until `next` accepts; proposing again (the zero address included) cancels a pending proposal.
|
|
911
911
|
* Indexed on-chain via the policy's AuthorityProposed.
|
|
912
912
|
*/
|
|
@@ -916,26 +916,26 @@ export async function fPoolProposeAuthority(c, a) {
|
|
|
916
916
|
/**
|
|
917
917
|
* Accept a pending proposal — step two; only the proposed address can. Indexed via the policy's
|
|
918
918
|
* AuthoritySet. On the desk's policy this clears the operator (pending and accepted) and voids the
|
|
919
|
-
* seller's list
|
|
919
|
+
* seller's list.
|
|
920
920
|
*/
|
|
921
921
|
export async function fPoolAcceptAuthority(c, a) {
|
|
922
922
|
return writePolicy(c, fPolicyBaseAbi, a, "acceptAuthority", []);
|
|
923
923
|
}
|
|
924
|
-
// ─── the desk's controls (PrivatePolicy
|
|
924
|
+
// ─── the desk's controls (PrivatePolicy) ───────────────────────────────
|
|
925
925
|
/** Turn the mint / swap gates on or off (the authority, on the desk's policy). `burn` is never gated. */
|
|
926
926
|
export async function fPoolSetGates(c, a) {
|
|
927
927
|
return writePolicy(c, privatePolicyAbi, a, "setGates", [a.gateMint, a.gateSwap]);
|
|
928
928
|
}
|
|
929
929
|
/**
|
|
930
930
|
* Add to or remove from the pool's MINTERS — who may mint, and swap (a zap in is both under one
|
|
931
|
-
* lock) — in one call (the authority, on the desk's policy
|
|
931
|
+
* lock) — in one call (the authority, on the desk's policy). The list is keyed by
|
|
932
932
|
* the authority that granted it: a handover starts the buyer with an empty one. Stamps the
|
|
933
933
|
* block: no swap lands in it (047).
|
|
934
934
|
*/
|
|
935
935
|
export async function fPoolSetMinters(c, a) {
|
|
936
936
|
return writePolicy(c, privatePolicyAbi, a, "setMinters", [a.who, a.allowed]);
|
|
937
937
|
}
|
|
938
|
-
/** Add to or remove from the pool's TAKERS — who may swap only — in one call (the authority
|
|
938
|
+
/** Add to or remove from the pool's TAKERS — who may swap only — in one call (the authority). Stamps the block. */
|
|
939
939
|
export async function fPoolSetTakers(c, a) {
|
|
940
940
|
return writePolicy(c, privatePolicyAbi, a, "setTakers", [a.who, a.allowed]);
|
|
941
941
|
}
|
|
@@ -955,12 +955,12 @@ export async function fPoolIsTaker(c, poolId, who, policy) {
|
|
|
955
955
|
export async function fPoolIsAllowed(c, poolId, who, policy) {
|
|
956
956
|
return readDesk(c, poolId, who, "isAllowed", policy);
|
|
957
957
|
}
|
|
958
|
-
/** Label the pool — the authority's own words on the pool's POLICY
|
|
958
|
+
/** Label the pool — the authority's own words on the pool's POLICY, mutable, never identity. At most 31 bytes of UTF-8. */
|
|
959
959
|
export async function fPoolSetName(c, a) {
|
|
960
960
|
return writePolicy(c, fPolicyBaseAbi, a, "setName", [textToBytes32(a.name)]);
|
|
961
961
|
}
|
|
962
962
|
/**
|
|
963
|
-
* What the PROTOCOL says an address is — "Keyrock" — on the REGISTRY
|
|
963
|
+
* What the PROTOCOL says an address is — "Keyrock" — on the REGISTRY. Only its
|
|
964
964
|
* owner, the LOG authority, may write it, which is what makes it an attestation rather than a
|
|
965
965
|
* claim anyone could make about themselves.
|
|
966
966
|
*/
|
|
@@ -996,7 +996,7 @@ async function registryAddress(c) {
|
|
|
996
996
|
throw new Error("logswap: this deployment carries no policy registry");
|
|
997
997
|
return registry;
|
|
998
998
|
}
|
|
999
|
-
/** Who runs the pool
|
|
999
|
+
/** Who runs the pool: the appointed operator, or the authority until one is. */
|
|
1000
1000
|
export function fPoolOperatorOf(s) {
|
|
1001
1001
|
return s.operator === ZERO_ADDRESS ? s.authority : s.operator;
|
|
1002
1002
|
}
|
|
@@ -1014,7 +1014,7 @@ export async function fPoolAcceptOperator(c, a) {
|
|
|
1014
1014
|
}
|
|
1015
1015
|
/**
|
|
1016
1016
|
* The next generation's composition (operator; private pools only; ONLY while the pool is
|
|
1017
|
-
* unseeded — between a retire and the seed that prices it
|
|
1017
|
+
* unseeded — between a retire and the seed that prices it). `weights` has one
|
|
1018
1018
|
* entry per leg the pool has ever had, in index order (0 retires a leg; indices are never reused),
|
|
1019
1019
|
* then one per base in `newBases`, appended; they sum to 1e18 exactly. No value moves: the
|
|
1020
1020
|
* following {@link fPoolSeed} names every reserve. A live reshape is {@link fPoolRelaunch} with
|
|
@@ -1083,7 +1083,7 @@ export async function discoverFPools(c, opts = {}) {
|
|
|
1083
1083
|
block: l.blockNumber ?? 0n,
|
|
1084
1084
|
seeded: q0 !== undefined,
|
|
1085
1085
|
q0: q0 ?? 0n,
|
|
1086
|
-
shape: kind === "pad" ? "launch" : "basket", // the policy's word, not n = 1: a mono POL is a pool
|
|
1086
|
+
shape: kind === "pad" ? "launch" : "basket", // the policy's word, not n = 1: a mono POL is a pool
|
|
1087
1087
|
};
|
|
1088
1088
|
}));
|
|
1089
1089
|
}
|
package/dist/keys.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export interface PoolKey {
|
|
|
23
23
|
/**
|
|
24
24
|
* The swap fee, WAD, fixed for the life of the market: `FEE_MIN` (1 bp) ≤ φ ≤ `FEE_MAX` (25%),
|
|
25
25
|
* or `0n`, which selects `DEFAULT_FEE` (2 bp) at read time. Four fields since C version 4
|
|
26
|
-
|
|
26
|
+
*: `kappa` and `alpha` left with the variance kernel, and `phiMin` — a floor with
|
|
27
27
|
* nothing above it — became `phi`. Every pool id changed with the shape.
|
|
28
28
|
*/
|
|
29
29
|
phi: bigint;
|
package/dist/liquidity.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* liquidity.ts — providing, editing and exiting a C position.
|
|
3
3
|
*
|
|
4
4
|
* A class is (ξ, μ, L): floor, cap, exposure. One primitive sets all three — `update` — and every
|
|
5
|
-
* edit is a constraint on it. The vocabulary follows the geometry
|
|
5
|
+
* edit is a constraint on it. The vocabulary follows the geometry: **the verb
|
|
6
6
|
* names the axis, the direction is a signed rung count**, and only two direction-words survive,
|
|
7
7
|
* because each names a wallet flow the user must see.
|
|
8
8
|
*
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* └─ reprice(ξ') R pinned: L' = L·e^{ξ' − ξ}, dormant only
|
|
16
16
|
* mint · burn · claim
|
|
17
17
|
*
|
|
18
|
-
* Every edit is ONE action of the router's batch (
|
|
18
|
+
* Every edit is ONE action of the router's batch (`actions.ts`), which is what
|
|
19
19
|
* lets it settle in kind, or in base, or in quote: `settleIn` appends the one swap that nets the
|
|
20
20
|
* other side, and the batch moves a single token. `previewEdit` is the lens's `previewUpdate` —
|
|
21
21
|
* the exact flows, mint fee and swept fees included — and is what an editor shows before its one
|
|
@@ -55,7 +55,7 @@ export interface MintArgs extends WriteOptions {
|
|
|
55
55
|
export declare function mint(c: LogswapClient, a: MintArgs): Promise<Hash>;
|
|
56
56
|
export interface CreateMarketArgs extends WriteOptions {
|
|
57
57
|
key: PoolKey;
|
|
58
|
-
/** Launch log-price. Bounded by the manager to ±46 (the price domain
|
|
58
|
+
/** Launch log-price. Bounded by the manager to ±46 (the price domain). */
|
|
59
59
|
x0: bigint;
|
|
60
60
|
/** The backstop's floor — the first mint's rung, permanent for the pool's life. */
|
|
61
61
|
targetFloor: bigint;
|
|
@@ -67,7 +67,7 @@ export interface CreateMarketArgs extends WriteOptions {
|
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
69
|
* Create a market ATOMICALLY: `initialize` at `x0` plus the backstop-establishing first mint in
|
|
70
|
-
* one transaction — the canonical creation path
|
|
70
|
+
* one transaction — the canonical creation path. The
|
|
71
71
|
* two-step path let an attacker seat the PERMANENT backstop at a hostile rung between an honest
|
|
72
72
|
* `initialize` and its first mint; here either both land or neither, and a front-run of the whole
|
|
73
73
|
* call reverts it without moving a wei. No cap: the first mint IS the backstop and must be
|
|
@@ -79,7 +79,7 @@ export interface ZapArgs extends WriteOptions {
|
|
|
79
79
|
/** Fund entirely from base (true) or entirely from quote (false). */
|
|
80
80
|
fundWithBase: boolean;
|
|
81
81
|
amountIn: bigint;
|
|
82
|
-
/** The least the swap leg may return
|
|
82
|
+
/** The least the swap leg may return: the zap's own slippage bound, as `swapExactIn`'s. Required. */
|
|
83
83
|
minSwapOut: bigint;
|
|
84
84
|
targetFloor: bigint;
|
|
85
85
|
cap?: bigint;
|
|
@@ -93,7 +93,7 @@ export interface ZapArgs extends WriteOptions {
|
|
|
93
93
|
*
|
|
94
94
|
* Routing the imbalanced part through the CURVE is the point, not an implementation detail. A
|
|
95
95
|
* pro-rata deposit of one asset would be a zero-slippage, zero-fee swap at stale spot — a subsidy
|
|
96
|
-
* paid by the incumbent LPs
|
|
96
|
+
* paid by the incumbent LPs. Paying the curve removes it.
|
|
97
97
|
*/
|
|
98
98
|
export declare function zapIn(c: LogswapClient, a: ZapArgs): Promise<Hash>;
|
|
99
99
|
export interface UpdateArgs extends WriteOptions {
|
|
@@ -124,7 +124,7 @@ export interface MoveArgs extends WriteOptions {
|
|
|
124
124
|
* Reposition at constant exposure — the L-pinned parent of `floor`, `cap` and `shift`; in kind.
|
|
125
125
|
*
|
|
126
126
|
* **Bound it.** The router used to settle this entry with no limit, which meant a reposition that
|
|
127
|
-
* priced differently by inclusion time could pull the whole allowance
|
|
127
|
+
* priced differently by inclusion time could pull the whole allowance.
|
|
128
128
|
* The bounds are required; {@link UNBOUNDED} is an explicit, visible opt-out.
|
|
129
129
|
*/
|
|
130
130
|
export declare function move(c: LogswapClient, a: MoveArgs): Promise<Hash>;
|
package/dist/liquidity.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* liquidity.ts — providing, editing and exiting a C position.
|
|
3
3
|
*
|
|
4
4
|
* A class is (ξ, μ, L): floor, cap, exposure. One primitive sets all three — `update` — and every
|
|
5
|
-
* edit is a constraint on it. The vocabulary follows the geometry
|
|
5
|
+
* edit is a constraint on it. The vocabulary follows the geometry: **the verb
|
|
6
6
|
* names the axis, the direction is a signed rung count**, and only two direction-words survive,
|
|
7
7
|
* because each names a wallet flow the user must see.
|
|
8
8
|
*
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* └─ reprice(ξ') R pinned: L' = L·e^{ξ' − ξ}, dormant only
|
|
16
16
|
* mint · burn · claim
|
|
17
17
|
*
|
|
18
|
-
* Every edit is ONE action of the router's batch (
|
|
18
|
+
* Every edit is ONE action of the router's batch (`actions.ts`), which is what
|
|
19
19
|
* lets it settle in kind, or in base, or in quote: `settleIn` appends the one swap that nets the
|
|
20
20
|
* other side, and the batch moves a single token. `previewEdit` is the lens's `previewUpdate` —
|
|
21
21
|
* the exact flows, mint fee and swept fees included — and is what an editor shows before its one
|
|
@@ -55,7 +55,7 @@ export async function mint(c, a) {
|
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
57
|
* Create a market ATOMICALLY: `initialize` at `x0` plus the backstop-establishing first mint in
|
|
58
|
-
* one transaction — the canonical creation path
|
|
58
|
+
* one transaction — the canonical creation path. The
|
|
59
59
|
* two-step path let an attacker seat the PERMANENT backstop at a hostile rung between an honest
|
|
60
60
|
* `initialize` and its first mint; here either both land or neither, and a front-run of the whole
|
|
61
61
|
* call reverts it without moving a wei. No cap: the first mint IS the backstop and must be
|
|
@@ -83,7 +83,7 @@ export async function createMarket(c, a) {
|
|
|
83
83
|
*
|
|
84
84
|
* Routing the imbalanced part through the CURVE is the point, not an implementation detail. A
|
|
85
85
|
* pro-rata deposit of one asset would be a zero-slippage, zero-fee swap at stale spot — a subsidy
|
|
86
|
-
* paid by the incumbent LPs
|
|
86
|
+
* paid by the incumbent LPs. Paying the curve removes it.
|
|
87
87
|
*/
|
|
88
88
|
export async function zapIn(c, a) {
|
|
89
89
|
return sendRouterWriteWithPermits(c, {
|
|
@@ -126,7 +126,7 @@ export async function update(c, a) {
|
|
|
126
126
|
* Reposition at constant exposure — the L-pinned parent of `floor`, `cap` and `shift`; in kind.
|
|
127
127
|
*
|
|
128
128
|
* **Bound it.** The router used to settle this entry with no limit, which meant a reposition that
|
|
129
|
-
* priced differently by inclusion time could pull the whole allowance
|
|
129
|
+
* priced differently by inclusion time could pull the whole allowance.
|
|
130
130
|
* The bounds are required; {@link UNBOUNDED} is an explicit, visible opt-out.
|
|
131
131
|
*/
|
|
132
132
|
export async function move(c, a) {
|
|
@@ -191,7 +191,7 @@ export async function edit(c, a) {
|
|
|
191
191
|
settle = settleInKind(key, recipient, { ...boundsFromFlows(p.dBase, p.dQuote, a.slippageBps), ...defined(a) });
|
|
192
192
|
}
|
|
193
193
|
else {
|
|
194
|
-
// the swept fees ride INSIDE dQuote (the manager burns by owner and nets them
|
|
194
|
+
// the swept fees ride INSIDE dQuote (the manager burns by owner and nets them),
|
|
195
195
|
// so quote's open delta after the update is dQuote itself — `fees` is reported for display only
|
|
196
196
|
const otherFlow = settleIn === "base" ? p.dQuote : p.dBase; // + = owed, − = released
|
|
197
197
|
const otherIsBase = settleIn === "quote";
|
package/dist/pools.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export interface PoolState {
|
|
|
26
26
|
reserveQuote: bigint;
|
|
27
27
|
/** Fee-per-unit-L accumulator: $\phi \cdot \mathrm{TV}(\log p)$. */
|
|
28
28
|
F: bigint;
|
|
29
|
-
/** Quadratic variation of log-price, $\Sigma = \sum_{\text{swaps}} (\Delta x_{\text{swap}})^2$ — one term per swap
|
|
29
|
+
/** Quadratic variation of log-price, $\Sigma = \sum_{\text{swaps}} (\Delta x_{\text{swap}})^2$ — one term per swap. */
|
|
30
30
|
bigSigma: bigint;
|
|
31
31
|
currentK: bigint;
|
|
32
32
|
protocolOwed: bigint;
|
|
@@ -37,7 +37,7 @@ export interface PoolState {
|
|
|
37
37
|
export declare function getPool(c: LogswapClient, key: PoolKey): Promise<PoolState>;
|
|
38
38
|
/**
|
|
39
39
|
* The market's fee: the key's `phi` with `0n` resolved to `DEFAULT_FEE`. Constant for the market's
|
|
40
|
-
* life (C version 4,
|
|
40
|
+
* life (C version 4, — `phiEff` and the variance kernel before). Reverts for a key
|
|
41
41
|
* nobody initialized, which `discoverMarkets` relies on to drop a stale indexer's rows.
|
|
42
42
|
*/
|
|
43
43
|
export declare function phiOf(c: LogswapClient, key: PoolKey): Promise<bigint>;
|
package/dist/pools.js
CHANGED
|
@@ -28,7 +28,7 @@ export async function getPool(c, key) {
|
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* The market's fee: the key's `phi` with `0n` resolved to `DEFAULT_FEE`. Constant for the market's
|
|
31
|
-
* life (C version 4,
|
|
31
|
+
* life (C version 4, — `phiEff` and the variance kernel before). Reverts for a key
|
|
32
32
|
* nobody initialized, which `discoverMarkets` relies on to drop a stale indexer's rows.
|
|
33
33
|
*/
|
|
34
34
|
export async function phiOf(c, key) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@logswap/sdk",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.56",
|
|
4
4
|
"description": "TypeScript SDK for Logswap, the liquidity primitive introducing the logarithmic invariant — typed wrappers over the CPoolManager / FPoolManager / Router / Lens surface.",
|
|
5
5
|
"license": "GPL-2.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -45,5 +45,6 @@
|
|
|
45
45
|
"repository": {
|
|
46
46
|
"type": "git",
|
|
47
47
|
"url": "git+https://github.com/logswap/logswap-sdk.git"
|
|
48
|
-
}
|
|
48
|
+
},
|
|
49
|
+
"homepage": "https://logswap.org"
|
|
49
50
|
}
|
package/src/actions.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* actions.ts — the router's transaction: a BATCH
|
|
2
|
+
* actions.ts — the router's transaction: a BATCH.
|
|
3
3
|
*
|
|
4
4
|
* `execute(actions, settle)` runs a list of actions — mint, burn, update, claim, swap, path, in any
|
|
5
5
|
* order, across any C markets — under ONE manager lock. Each action accrues deltas on the router
|
package/src/admin.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* admin — the protocol's writes: the C manager's cut of the mint fee (the F manager's is a
|
|
3
|
-
* constant
|
|
3
|
+
* constant), the policies a pool may be born with (the registry's), the
|
|
4
4
|
* policies' own numbers, and the two-step collector handover. Plain writes to the managers,
|
|
5
5
|
* the registry and the policies; no router.
|
|
6
6
|
*
|
|
7
|
-
* One vocabulary
|
|
7
|
+
* One vocabulary: both managers call the protocol's cut of the mint fee
|
|
8
8
|
* `MINT_FEE_PROTOCOL_CUT`; C sets it through `setFeeParams(uint256)`, F holds it as a constant
|
|
9
|
-
* (049). The harvest's cut is the policy's answer at every harvest
|
|
9
|
+
* (049). The harvest's cut is the policy's answer at every harvest, set on the
|
|
10
10
|
* policy (`setHarvestCut`) and capped by the manager (`HARVEST_CUT_MAX`); the release's
|
|
11
11
|
* protocol share likewise (`POT_CUT_MAX`).
|
|
12
12
|
*/
|
|
@@ -29,12 +29,12 @@ function write(c: LogswapClient, address: Address, abi: readonly unknown[], func
|
|
|
29
29
|
export async function setFeeParamsC(c: LogswapClient, mintFeeProtocolCutWad: bigint): Promise<Hash> {
|
|
30
30
|
return write(c, c.addresses.cPoolManager, cPoolManagerAbi, "setFeeParams", [mintFeeProtocolCutWad]);
|
|
31
31
|
}
|
|
32
|
-
/** The F manager's `MINT_FEE_PROTOCOL_CUT` — a constant since F version 18
|
|
32
|
+
/** The F manager's `MINT_FEE_PROTOCOL_CUT` — a constant since F version 18; there is no setter. */
|
|
33
33
|
export async function fMintFeeProtocolCut(c: LogswapClient): Promise<bigint> {
|
|
34
34
|
return c.public.readContract({ address: c.addresses.fPoolManager as Address, abi: fPoolManagerAbi, functionName: "MINT_FEE_PROTOCOL_CUT" } as never) as Promise<bigint>;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
// ─── the registry
|
|
37
|
+
// ─── the registry: the LOG authority's, not the collector's ─────────────────
|
|
38
38
|
|
|
39
39
|
const ZERO = "0x0000000000000000000000000000000000000000" as const;
|
|
40
40
|
|
|
@@ -58,7 +58,7 @@ export async function policyApproved(c: LogswapClient, policy: Address): Promise
|
|
|
58
58
|
/** One policy on the registry's list, with what it says it is. */
|
|
59
59
|
export interface RegistryEntry {
|
|
60
60
|
policy: Address;
|
|
61
|
-
/** The policy's own `kind()` tag
|
|
61
|
+
/** The policy's own `kind()` tag — what a pool born under it is. */
|
|
62
62
|
kind: FPoolKind;
|
|
63
63
|
name: string;
|
|
64
64
|
/** The block it closes to new pools from; 0 = open. */
|
|
@@ -68,7 +68,7 @@ export interface RegistryEntry {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
|
-
* Every policy listed, sunset ones included — one flat list
|
|
71
|
+
* Every policy listed, sunset ones included — one flat list, each with the kind
|
|
72
72
|
* it says it is; `kind` narrows it to one, which is what a create form's dropdown reads. Empty
|
|
73
73
|
* with no registry.
|
|
74
74
|
*/
|
|
@@ -138,7 +138,7 @@ export async function setPolicyApproved(c: LogswapClient, policy: Address, appro
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
/**
|
|
141
|
-
* Move a pool to another approved policy of the same kind
|
|
141
|
+
* Move a pool to another approved policy of the same kind: the registry
|
|
142
142
|
* owner's alone, orchestrated on the registry — `migrate(manager, poolId, to)`. The new policy
|
|
143
143
|
* takes the authority and the name from the old; the operator and the lists void; no swap lands
|
|
144
144
|
* in the block.
|