@logswap/sdk 0.5.35 → 0.5.37
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/dist/client.d.ts +1 -1
- package/dist/client.js +5 -1
- package/dist/fpool.d.ts +3655 -23
- package/dist/fpool.js +139 -28
- package/dist/generated.d.ts +1823 -248
- package/dist/generated.js +1378 -238
- package/package.json +2 -2
- package/src/client.ts +5 -1
- package/src/fpool.ts +205 -41
- package/src/generated.ts +1380 -238
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@logswap/sdk",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.37",
|
|
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",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"clean": "rm -rf dist src/generated.ts",
|
|
27
27
|
"test": "vitest run",
|
|
28
28
|
"test:watch": "vitest",
|
|
29
|
-
"prepublishOnly": "npm run build"
|
|
29
|
+
"prepublishOnly": "npm run codegen && npm run build"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"viem": "^2.0.0"
|
package/src/client.ts
CHANGED
|
@@ -71,7 +71,11 @@ export const EXPECTED_VERSION = 3n;
|
|
|
71
71
|
* passes it; when one lands, raise this constant in the same change, which is the discipline
|
|
72
72
|
* `EXPECTED_VERSION` enforces mechanically and this one asks for.
|
|
73
73
|
*/
|
|
74
|
-
|
|
74
|
+
// 7 (2026-09-15): the reserves are the state and the marks derived, `lockStrike`, the dividend
|
|
75
|
+
// harvest, the relaunch (`dissolve(poolId, successor)`, `rollIn`), the reserve-named seed, the
|
|
76
|
+
// sponsor facet — decisions 025–031. A 5 or 6 deployment reads with this SDK but every F write
|
|
77
|
+
// below `seed` / `dissolve` / `setLegL` / `admitLeg` has moved its signature.
|
|
78
|
+
export const EXPECTED_F_VERSION = 7n;
|
|
75
79
|
|
|
76
80
|
export async function assertVersion(c: LogswapClient, expected = EXPECTED_VERSION): Promise<void> {
|
|
77
81
|
const { cPoolManagerAbi } = await import("./generated.js");
|
package/src/fpool.ts
CHANGED
|
@@ -23,8 +23,17 @@
|
|
|
23
23
|
* `addresses.router`.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import { toFunctionSelector, type Address, type Hash, type Hex } from "viem";
|
|
27
|
-
import { fPoolManagerAbi, logswapRouterAbi } from "./generated.js";
|
|
26
|
+
import { encodeFunctionData, toFunctionSelector, type Address, type Hash, type Hex } from "viem";
|
|
27
|
+
import { fPoolManagerAbi as fPoolPrimitiveAbi, fPoolSponsorAbi, logswapRouterAbi } from "./generated.js";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The F manager's ABI is the UNION of its two compiled halves (decisions 031): `FPoolManager`
|
|
31
|
+
* holds the primitive and forwards every other selector from its fallback to `FPoolSponsor` —
|
|
32
|
+
* the lever, `claim`, `dissolve`, the handover, the gates, the desk, the names — by delegatecall.
|
|
33
|
+
* One address from outside, so one ABI here; both halves carry the base's events and errors,
|
|
34
|
+
* and viem tolerates the duplicates.
|
|
35
|
+
*/
|
|
36
|
+
export const fPoolManagerAbi = [...fPoolPrimitiveAbi, ...fPoolSponsorAbi] as const;
|
|
28
37
|
import type { LogswapClient } from "./client.js";
|
|
29
38
|
|
|
30
39
|
const WAD = 10n ** 18n;
|
|
@@ -70,12 +79,18 @@ export interface FPoolState {
|
|
|
70
79
|
gateSwap: boolean;
|
|
71
80
|
/** The block of the last lever / composition action: no swap runs in it. */
|
|
72
81
|
restructureBlock: number;
|
|
73
|
-
/**
|
|
74
|
-
|
|
82
|
+
/**
|
|
83
|
+
* The strike is locked (decisions 027, formerly `feesOnly`): `harvest` resets the floor to θ₀
|
|
84
|
+
* and never past it, so only income can leave; and the pool cannot be dissolved while it bids.
|
|
85
|
+
* The pad's promise. Pairs with a locked seed (shares at 0xdead) — the class is the two bits.
|
|
86
|
+
*/
|
|
87
|
+
lockStrike: boolean;
|
|
75
88
|
seeded: boolean;
|
|
76
89
|
dissolved: boolean;
|
|
90
|
+
/** The pool this one dissolved into (decisions 025) — the relaunch's lineage; zero when none. */
|
|
91
|
+
successor: Hex;
|
|
77
92
|
totalSupply: bigint;
|
|
78
|
-
/**
|
|
93
|
+
/** What the pool holds of each base — the STATE since decisions 026; the mark `x` is derived from it. */
|
|
79
94
|
reserves: bigint[];
|
|
80
95
|
}
|
|
81
96
|
|
|
@@ -97,7 +112,7 @@ export async function getFPool(c: LogswapClient, poolId: Hex): Promise<FPoolStat
|
|
|
97
112
|
quote: Address;
|
|
98
113
|
phi: bigint;
|
|
99
114
|
authority: Address;
|
|
100
|
-
|
|
115
|
+
lockStrike: boolean;
|
|
101
116
|
seeded: boolean;
|
|
102
117
|
dissolved: boolean;
|
|
103
118
|
n: number;
|
|
@@ -115,6 +130,7 @@ export async function getFPool(c: LogswapClient, poolId: Hex): Promise<FPoolStat
|
|
|
115
130
|
minBuffer: bigint;
|
|
116
131
|
incomeTaken: bigint;
|
|
117
132
|
name: Hex;
|
|
133
|
+
successor: Hex;
|
|
118
134
|
}>("getPool", [poolId]);
|
|
119
135
|
|
|
120
136
|
// A pool that was never created reads as an all-zero struct rather than reverting, so the
|
|
@@ -136,11 +152,9 @@ export async function getFPool(c: LogswapClient, poolId: Hex): Promise<FPoolStat
|
|
|
136
152
|
|
|
137
153
|
const bases = legs.map((l) => l[0]);
|
|
138
154
|
const weights = legs.map((l) => l[1]);
|
|
139
|
-
const x = legs.map((l) => l[2]);
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const reserves = legs.map((l) => l[3]);
|
|
143
|
-
const { quote, Q, L, phi, theta0, bigSigma, authority, pendingAuthority, operator, minBuffer, gateMint, gateSwap, restructureBlock, feesOnly, seeded, dissolved } = p;
|
|
155
|
+
const x = legs.map((l) => l[2]); // derived by the manager: x_j = ln(w_j·L / R_j) (decisions 026)
|
|
156
|
+
const reserves = legs.map((l) => l[3]); // the state
|
|
157
|
+
const { quote, Q, L, phi, theta0, bigSigma, authority, pendingAuthority, operator, minBuffer, gateMint, gateSwap, restructureBlock, lockStrike, seeded, dissolved, successor } = p;
|
|
144
158
|
const totalSupply = p.shares;
|
|
145
159
|
|
|
146
160
|
return {
|
|
@@ -164,9 +178,10 @@ export async function getFPool(c: LogswapClient, poolId: Hex): Promise<FPoolStat
|
|
|
164
178
|
gateMint,
|
|
165
179
|
gateSwap,
|
|
166
180
|
restructureBlock: Number(restructureBlock),
|
|
167
|
-
|
|
181
|
+
lockStrike,
|
|
168
182
|
seeded,
|
|
169
183
|
dissolved,
|
|
184
|
+
successor,
|
|
170
185
|
totalSupply,
|
|
171
186
|
reserves,
|
|
172
187
|
};
|
|
@@ -355,16 +370,92 @@ export async function fPoolZapOut(
|
|
|
355
370
|
);
|
|
356
371
|
}
|
|
357
372
|
|
|
373
|
+
/**
|
|
374
|
+
* Roll a dissolved pool's bundle into its successor (decisions 025), on the router under one
|
|
375
|
+
* lock: burn `shares` of `fromPool` in place — the legs, the quote and any unpulled dividend come
|
|
376
|
+
* back — buy through `toPool`'s own curve only what its ratio lacks, mint `dL` of it to `to`, and
|
|
377
|
+
* refund the rest in kind. Quote the bundle does not cover is pulled from the payer, at most
|
|
378
|
+
* `maxQuoteIn`; surplus base is refunded, never sold. Size `dL` with {@link fPoolPreviewRollIn}.
|
|
379
|
+
* The router must be the caller's ERC-6909 operator ({@link approveRouterForFPool}).
|
|
380
|
+
*/
|
|
381
|
+
export async function fPoolRollIn(
|
|
382
|
+
c: LogswapClient,
|
|
383
|
+
a: {
|
|
384
|
+
fromPool: Hex;
|
|
385
|
+
toPool: Hex;
|
|
386
|
+
shares: bigint;
|
|
387
|
+
dL: bigint;
|
|
388
|
+
maxQuoteIn?: bigint;
|
|
389
|
+
minShares?: bigint;
|
|
390
|
+
to?: Address;
|
|
391
|
+
account: Address;
|
|
392
|
+
deadline?: bigint;
|
|
393
|
+
},
|
|
394
|
+
) {
|
|
395
|
+
const to = a.to ?? a.account;
|
|
396
|
+
return writeRouter(
|
|
397
|
+
c,
|
|
398
|
+
"rollIn",
|
|
399
|
+
[a.fromPool, a.toPool, a.shares, a.dL, a.maxQuoteIn ?? 0n, a.minShares ?? 0n, to, a.deadline ?? defaultDeadline()],
|
|
400
|
+
a.account,
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* The roll `holder`'s `shares` of `fromPool` fund into `toPool` WITHOUT a trade: the largest `dL`
|
|
406
|
+
* the bundle's base covers on every successor leg, and the quote the bundle is short of (pass it
|
|
407
|
+
* as `maxQuoteIn`) or over (refunded — the up direction's distribution) at that `dL`. A
|
|
408
|
+
* successor leg the bundle does not hold makes `dL` zero: such a roll must buy, so size it below
|
|
409
|
+
* with `previewZapIn` in mind.
|
|
410
|
+
*/
|
|
411
|
+
export async function fPoolPreviewRollIn(
|
|
412
|
+
c: LogswapClient,
|
|
413
|
+
fromPool: Hex,
|
|
414
|
+
toPool: Hex,
|
|
415
|
+
holder: Address,
|
|
416
|
+
shares: bigint,
|
|
417
|
+
): Promise<{ dL: bigint; quoteShort: bigint; quoteExcess: bigint }> {
|
|
418
|
+
const { logswapLensAbi } = await import("./generated.js");
|
|
419
|
+
const [dL, quoteShort, quoteExcess] = (await c.public.readContract({
|
|
420
|
+
address: c.addresses.lens,
|
|
421
|
+
abi: logswapLensAbi,
|
|
422
|
+
functionName: "previewRollIn",
|
|
423
|
+
args: [fromPool, toPool, holder, shares],
|
|
424
|
+
} as never)) as readonly [bigint, bigint, bigint];
|
|
425
|
+
return { dL, quoteShort, quoteExcess };
|
|
426
|
+
}
|
|
427
|
+
|
|
358
428
|
// ─── the floor lever (authority only) ─────────────────────────────────────────
|
|
359
429
|
|
|
360
430
|
/**
|
|
361
|
-
* Remove quote, lifting θ — price-neutral,
|
|
362
|
-
*
|
|
431
|
+
* Remove quote, lifting θ — price-neutral, no base moves, and since decisions 028 a DIVIDEND to
|
|
432
|
+
* every share: the amount goes into the pool's pot and each holder's slice is settled lazily on
|
|
433
|
+
* their next transfer, mint or burn, or pulled with {@link fPoolClaim}. The sponsor's own slice —
|
|
434
|
+
* its shares' and the locked seed's at 0xdead — is pushed to `to` at once. Under `lockStrike`
|
|
435
|
+
* the lift stops at θ₀ (income only); on every live pool it stops at `LEVER_FLOOR` (Q/L ≥ ln 1.25).
|
|
363
436
|
*/
|
|
364
437
|
export async function fPoolHarvest(c: LogswapClient, a: { poolId: Hex; amount: bigint; to?: Address; account: Address }) {
|
|
365
438
|
return writeFPool(c, a.poolId, "harvest", [a.amount, a.to ?? a.account], a.account);
|
|
366
439
|
}
|
|
367
440
|
|
|
441
|
+
/** Pull one's settled dividend (decisions 028) without moving shares; anyone with shares. */
|
|
442
|
+
export async function fPoolClaim(c: LogswapClient, a: { poolId: Hex; to?: Address; account: Address }) {
|
|
443
|
+
return writeFPool(c, a.poolId, "claim", [a.to ?? a.account], a.account);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/** A holder's dividend as of now — banked plus pending on the current balance (decisions 028). */
|
|
447
|
+
export async function fPoolDividendOf(c: LogswapClient, poolId: Hex, holder: Address): Promise<bigint> {
|
|
448
|
+
return c.public.readContract({
|
|
449
|
+
address: c.addresses.fPoolManager!,
|
|
450
|
+
abi: fPoolManagerAbi,
|
|
451
|
+
functionName: "dividendOf",
|
|
452
|
+
args: [poolId, holder],
|
|
453
|
+
} as never) as Promise<bigint>;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/** The lever's floor: `harvest` may not take Q/L under ln 1.25 — the floor stays ≥ 20% below the mark (decisions 025). */
|
|
457
|
+
export const LEVER_FLOOR = 223143551314209755n;
|
|
458
|
+
|
|
368
459
|
/** Commit quote, deepening θ — the other sign of `harvest`, the same word as the C floor edit (decisions 011). The mark does not move: governance may write θ, never x. */
|
|
369
460
|
export async function fPoolDeepen(c: LogswapClient, a: { poolId: Hex; amount: bigint; account: Address }) {
|
|
370
461
|
return writeFPool(c, a.poolId, "deepen", [a.amount], a.account);
|
|
@@ -396,6 +487,19 @@ async function writeFPool(c: LogswapClient, poolId: Hex, functionName: string, a
|
|
|
396
487
|
return wallet.writeContract(request as never);
|
|
397
488
|
}
|
|
398
489
|
|
|
490
|
+
/** A manager write that is NOT keyed by a poolId — `multicall`. */
|
|
491
|
+
async function writeFPool0(c: LogswapClient, functionName: string, args: unknown[], account: Address) {
|
|
492
|
+
const wallet = requireWallet(c);
|
|
493
|
+
const { request } = await c.public.simulateContract({
|
|
494
|
+
address: c.addresses.fPoolManager!,
|
|
495
|
+
abi: fPoolManagerAbi,
|
|
496
|
+
functionName,
|
|
497
|
+
args,
|
|
498
|
+
account,
|
|
499
|
+
} as never);
|
|
500
|
+
return wallet.writeContract(request as never);
|
|
501
|
+
}
|
|
502
|
+
|
|
399
503
|
async function writeRouter(
|
|
400
504
|
c: LogswapClient,
|
|
401
505
|
functionName: string,
|
|
@@ -599,8 +703,8 @@ export interface FPoolCreateArgs {
|
|
|
599
703
|
weights: bigint[];
|
|
600
704
|
/** Fixed fee, WAD. The base-for-base fee is pinned at 2φ on-chain. */
|
|
601
705
|
phi: bigint;
|
|
602
|
-
/** true: the
|
|
603
|
-
|
|
706
|
+
/** true: the strike is locked — harvest stops at θ₀ and the pool cannot be dissolved live (the pad's posture; decisions 027). */
|
|
707
|
+
lockStrike: boolean;
|
|
604
708
|
authority: Address;
|
|
605
709
|
/**
|
|
606
710
|
* The differentiator, and nothing else. Identity is the key's hash, so one sponsor cannot run
|
|
@@ -640,7 +744,7 @@ export async function fPoolInitialize(c: LogswapClient, a: FPoolCreateArgs) {
|
|
|
640
744
|
const sum = a.weights.reduce((x, y) => x + y, 0n);
|
|
641
745
|
if (sum !== 10n ** 18n) throw new Error(`logswap: weights sum to ${sum}, expected 1e18`);
|
|
642
746
|
const { bases, companions } = sortFPoolLegs(a.bases, a.weights);
|
|
643
|
-
const key = { quote: a.quote, bases, weights: companions[0]!, phi: a.phi,
|
|
747
|
+
const key = { quote: a.quote, bases, weights: companions[0]!, phi: a.phi, lockStrike: a.lockStrike, authority: a.authority, salt: a.salt ?? ZERO_SALT };
|
|
644
748
|
const wallet = requireWallet(c);
|
|
645
749
|
const { request } = await c.public.simulateContract({
|
|
646
750
|
address: c.addresses.fPoolManager!,
|
|
@@ -655,7 +759,7 @@ export async function fPoolInitialize(c: LogswapClient, a: FPoolCreateArgs) {
|
|
|
655
759
|
/** The pool id is the key's hash — pure, so it can be read before or after creation. */
|
|
656
760
|
export async function fPoolIdOf(c: LogswapClient, a: Omit<FPoolCreateArgs, "account">): Promise<Hex> {
|
|
657
761
|
const { bases, companions } = sortFPoolLegs(a.bases, a.weights);
|
|
658
|
-
const key = { quote: a.quote, bases, weights: companions[0]!, phi: a.phi,
|
|
762
|
+
const key = { quote: a.quote, bases, weights: companions[0]!, phi: a.phi, lockStrike: a.lockStrike, authority: a.authority, salt: a.salt ?? ZERO_SALT };
|
|
659
763
|
return c.public.readContract({
|
|
660
764
|
address: c.addresses.fPoolManager!,
|
|
661
765
|
abi: fPoolManagerAbi,
|
|
@@ -665,20 +769,81 @@ export async function fPoolIdOf(c: LogswapClient, a: Omit<FPoolCreateArgs, "acco
|
|
|
665
769
|
}
|
|
666
770
|
|
|
667
771
|
/**
|
|
668
|
-
*
|
|
669
|
-
*
|
|
670
|
-
*
|
|
772
|
+
* The reserve a leg holds at a mark: `R = Lj·e^{−x}`, WAD math. The seed names RESERVES since
|
|
773
|
+
* decisions 029 — the sponsor states holdings and the price follows, `p = Lj / R` — so this is
|
|
774
|
+
* the one conversion from a price to what the pool will hold, done here, on the way in. Float
|
|
775
|
+
* precision (~1e-16 relative) is what a seed needs: any reserve is a legal seed, and the mark
|
|
776
|
+
* the pool derives from it is the one the sponsor meant to within that.
|
|
777
|
+
*/
|
|
778
|
+
export function fPoolReserveAt(Lj: bigint, x: bigint): bigint {
|
|
779
|
+
const e = Math.exp(-Number(x) / 1e18);
|
|
780
|
+
return (Lj * BigInt(Math.round(e * 1e18))) / 10n ** 18n;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* Arm the pool: deposit `r0[j]` of each base plus `Q0` of quote against exposure `L0`. Pass either
|
|
785
|
+
* the reserves outright (`r0`) or the marks the pool should open at (`x0`, converted here with
|
|
786
|
+
* {@link fPoolReserveAt} against the key's weights). Authority-only on-chain (an open seed lets
|
|
787
|
+
* anyone front-run the creator for the strike). Arrays align with the SORTED bases — use
|
|
788
|
+
* {@link sortFPoolLegs} on (bases, weights, x0) together when building forms.
|
|
671
789
|
*/
|
|
672
790
|
export async function fPoolSeed(
|
|
673
791
|
c: LogswapClient,
|
|
674
|
-
a: { poolId: Hex; L0: bigint;
|
|
792
|
+
a: { poolId: Hex; L0: bigint; Q0: bigint; account: Address } & ({ r0: bigint[] } | { x0: bigint[]; weights: bigint[] }),
|
|
675
793
|
) {
|
|
676
|
-
|
|
794
|
+
const r0 = "r0" in a ? a.r0 : a.x0.map((x, j) => fPoolReserveAt((a.weights[j]! * a.L0) / 10n ** 18n, x));
|
|
795
|
+
return writeFPool(c, a.poolId, "seed", [a.L0, r0, a.Q0], a.account);
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* End of life (decisions 025). Allowed at Q ≤ L/1e9 on every pool — the market filled the ask —
|
|
800
|
+
* and on a pool that is not strike-locked at any Q, provided `successor` names an initialized
|
|
801
|
+
* pool of the same authority and quote: the relaunch. After it every share is a frozen in-kind
|
|
802
|
+
* claim redeemed by `burn` (or rolled with {@link fPoolRollIn}), forever; the pool's `successor`
|
|
803
|
+
* carries the lineage. Never a second dissolve on one pool: the successor is a NEW pool.
|
|
804
|
+
*/
|
|
805
|
+
export async function fPoolDissolve(c: LogswapClient, a: { poolId: Hex; successor?: Hex; account: Address }) {
|
|
806
|
+
return writeFPool(c, a.poolId, "dissolve", [a.successor ?? ZERO_SALT], a.account);
|
|
677
807
|
}
|
|
678
808
|
|
|
679
|
-
/**
|
|
680
|
-
|
|
681
|
-
|
|
809
|
+
/**
|
|
810
|
+
* The sponsor's relaunch as ONE transaction (decisions 025): `initialize` the successor key,
|
|
811
|
+
* `dissolve` the old pool into it, `burn` the sponsor's own shares, `seed` the successor with what
|
|
812
|
+
* came back — the manager's `multicall`, the sponsor as sender throughout. Gates, allowlist,
|
|
813
|
+
* operator, floor guard and name are re-applied afterwards, or appended to `extra` pre-encoded
|
|
814
|
+
* against {@link fPoolManagerAbi}. Returns the tx hash; the successor's id is {@link fPoolIdOf}
|
|
815
|
+
* of `nextKey`.
|
|
816
|
+
*/
|
|
817
|
+
export async function fPoolRelaunch(
|
|
818
|
+
c: LogswapClient,
|
|
819
|
+
a: {
|
|
820
|
+
poolId: Hex;
|
|
821
|
+
nextKey: Omit<FPoolCreateArgs, "account">;
|
|
822
|
+
/** the sponsor's old shares to burn — its whole balance, usually */
|
|
823
|
+
shares: bigint;
|
|
824
|
+
L0: bigint;
|
|
825
|
+
Q0: bigint;
|
|
826
|
+
r0: bigint[];
|
|
827
|
+
extra?: Hex[];
|
|
828
|
+
account: Address;
|
|
829
|
+
},
|
|
830
|
+
) {
|
|
831
|
+
const { bases, companions } = sortFPoolLegs(a.nextKey.bases, a.nextKey.weights);
|
|
832
|
+
const key = {
|
|
833
|
+
quote: a.nextKey.quote, bases, weights: companions[0]!, phi: a.nextKey.phi, lockStrike: a.nextKey.lockStrike,
|
|
834
|
+
authority: a.nextKey.authority, salt: a.nextKey.salt ?? ZERO_SALT,
|
|
835
|
+
};
|
|
836
|
+
const next = await fPoolIdOf(c, a.nextKey);
|
|
837
|
+
const enc = (functionName: string, args: unknown[]) =>
|
|
838
|
+
encodeFunctionData({ abi: fPoolManagerAbi, functionName, args } as never) as Hex;
|
|
839
|
+
const calls: Hex[] = [
|
|
840
|
+
enc("initialize", [key]),
|
|
841
|
+
enc("dissolve", [a.poolId, next]),
|
|
842
|
+
enc("burn", [a.poolId, a.account, a.shares, 0n]),
|
|
843
|
+
enc("seed", [next, a.L0, a.r0, a.Q0]),
|
|
844
|
+
...(a.extra ?? []),
|
|
845
|
+
];
|
|
846
|
+
return writeFPool0(c, "multicall", [calls], a.account);
|
|
682
847
|
}
|
|
683
848
|
|
|
684
849
|
/**
|
|
@@ -697,9 +862,6 @@ export async function fPoolAcceptAuthority(c: LogswapClient, a: { poolId: Hex; a
|
|
|
697
862
|
|
|
698
863
|
// ─── the sponsor's controls and the desk (contracts bd3dd87, decisions 021) ───────────────
|
|
699
864
|
|
|
700
|
-
/** `setLegL`'s "keep the stored mark" sentinel — the only legal `x` for a live leg. */
|
|
701
|
-
export const NO_X = -(2n ** 255n);
|
|
702
|
-
|
|
703
865
|
/** Turn the mint / swap gates on or off (authority). `burn` is never gated. */
|
|
704
866
|
export async function fPoolSetGates(
|
|
705
867
|
c: LogswapClient,
|
|
@@ -773,22 +935,24 @@ export async function fPoolRaiseMinBuffer(c: LogswapClient, a: { poolId: Hex; mi
|
|
|
773
935
|
|
|
774
936
|
/**
|
|
775
937
|
* Set leg `j`'s liquidity (operator, sole LP only): grow, shrink, retire (`newLj = 0`), or re-admit
|
|
776
|
-
* a retired leg
|
|
777
|
-
*
|
|
938
|
+
* a retired leg holding `r` of the base (decisions 029 — the price follows, `p = newLj / r`; use
|
|
939
|
+
* {@link fPoolReserveAt} from a mark). For a live leg leave `r` undefined — its price is the
|
|
940
|
+
* market's, the reserve scales with the liquidity. Base moves single-sidedly through the lock;
|
|
941
|
+
* shares adjust to hold the share value.
|
|
778
942
|
*/
|
|
779
943
|
export async function fPoolSetLegL(
|
|
780
944
|
c: LogswapClient,
|
|
781
|
-
a: { poolId: Hex; j: number; newLj: bigint;
|
|
945
|
+
a: { poolId: Hex; j: number; newLj: bigint; r?: bigint; account: Address },
|
|
782
946
|
) {
|
|
783
|
-
return writeFPool(c, a.poolId, "setLegL", [BigInt(a.j), a.newLj, a.
|
|
947
|
+
return writeFPool(c, a.poolId, "setLegL", [BigInt(a.j), a.newLj, a.r ?? 0n], a.account);
|
|
784
948
|
}
|
|
785
949
|
|
|
786
|
-
/** Admit a base the pool has never held
|
|
950
|
+
/** Admit a base the pool has never held: `R` of it against liquidity `Lj`, so at `p = Lj / R` (operator, sole LP only). */
|
|
787
951
|
export async function fPoolAdmitLeg(
|
|
788
952
|
c: LogswapClient,
|
|
789
|
-
a: { poolId: Hex; base: Address; Lj: bigint;
|
|
953
|
+
a: { poolId: Hex; base: Address; Lj: bigint; R: bigint; account: Address },
|
|
790
954
|
) {
|
|
791
|
-
return writeFPool(c, a.poolId, "admitLeg", [a.base, a.Lj, a.
|
|
955
|
+
return writeFPool(c, a.poolId, "admitLeg", [a.base, a.Lj, a.R], a.account);
|
|
792
956
|
}
|
|
793
957
|
|
|
794
958
|
/**
|
|
@@ -819,7 +983,7 @@ export interface DiscoveredFPool {
|
|
|
819
983
|
bases: Address[];
|
|
820
984
|
weights: bigint[];
|
|
821
985
|
phi: bigint;
|
|
822
|
-
|
|
986
|
+
lockStrike: boolean;
|
|
823
987
|
authority: Address;
|
|
824
988
|
/** The block the pool was initialized in — its age, for annualising realized income. */
|
|
825
989
|
block: bigint;
|
|
@@ -838,7 +1002,7 @@ export interface DiscoveredFPool {
|
|
|
838
1002
|
|
|
839
1003
|
/**
|
|
840
1004
|
* Every F pool ever created, from `Initialize` logs alone. Possible only because the event
|
|
841
|
-
* carries the full key preimage (bases, weights, phi,
|
|
1005
|
+
* carries the full key preimage (bases, weights, phi, lockStrike) — the poolId is a hash and could
|
|
842
1006
|
* never be inverted; contracts PR #17 exists for exactly this call.
|
|
843
1007
|
*/
|
|
844
1008
|
export async function discoverFPools(
|
|
@@ -869,7 +1033,7 @@ export async function discoverFPools(
|
|
|
869
1033
|
return logs.map((l) => {
|
|
870
1034
|
const a = l.args as {
|
|
871
1035
|
poolId: Hex; quote: Address; authority: Address; bases: readonly Address[];
|
|
872
|
-
weights: readonly bigint[]; phi: bigint;
|
|
1036
|
+
weights: readonly bigint[]; phi: bigint; lockStrike: boolean;
|
|
873
1037
|
};
|
|
874
1038
|
const q0 = q0Of.get(a.poolId.toLowerCase());
|
|
875
1039
|
return {
|
|
@@ -878,7 +1042,7 @@ export async function discoverFPools(
|
|
|
878
1042
|
bases: [...a.bases],
|
|
879
1043
|
weights: [...a.weights],
|
|
880
1044
|
phi: a.phi,
|
|
881
|
-
|
|
1045
|
+
lockStrike: a.lockStrike,
|
|
882
1046
|
authority: a.authority,
|
|
883
1047
|
block: l.blockNumber ?? 0n,
|
|
884
1048
|
seeded: q0 !== undefined,
|
|
@@ -922,7 +1086,7 @@ export async function fPoolShareHolders(
|
|
|
922
1086
|
.sort((a, b) => (b.shares > a.shares ? 1 : -1));
|
|
923
1087
|
}
|
|
924
1088
|
|
|
925
|
-
/** Every F pool's state in one lens call (the raw manager struct: quote, phi, authority,
|
|
1089
|
+
/** Every F pool's state in one lens call (the raw manager struct: quote, phi, authority, lockStrike, seeded, dissolved, successor, n, Q, L, shares, theta0, bigSigma, leverTheta). */
|
|
926
1090
|
export async function getFPoolsRaw(c: LogswapClient, poolIds: Hex[]): Promise<readonly unknown[]> {
|
|
927
1091
|
const { logswapLensAbi } = await import("./generated.js");
|
|
928
1092
|
return (await c.public.readContract({ address: c.addresses.lens, abi: logswapLensAbi, functionName: "getFPools", args: [poolIds] } as never)) as readonly unknown[];
|