@logswap/sdk 0.5.36 → 0.5.38
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 +8 -1
- package/dist/fpool.d.ts +3888 -27
- package/dist/fpool.js +198 -35
- package/dist/generated.d.ts +2078 -292
- package/dist/generated.js +1479 -193
- package/package.json +2 -2
- package/src/client.ts +8 -1
- package/src/fpool.ts +290 -51
- package/src/generated.ts +1481 -193
package/dist/fpool.js
CHANGED
|
@@ -22,8 +22,16 @@
|
|
|
22
22
|
* twice, forever. One router is one spender — see `fPoolZapIn`/`fPoolZapOut` below, which target
|
|
23
23
|
* `addresses.router`.
|
|
24
24
|
*/
|
|
25
|
-
import { toFunctionSelector } from "viem";
|
|
26
|
-
import { fPoolManagerAbi, logswapRouterAbi } from "./generated.js";
|
|
25
|
+
import { encodeFunctionData, toFunctionSelector } from "viem";
|
|
26
|
+
import { fPoolManagerAbi as fPoolPrimitiveAbi, fPoolSponsorAbi, logswapRouterAbi } from "./generated.js";
|
|
27
|
+
/**
|
|
28
|
+
* The F manager's ABI is the UNION of its two compiled halves (decisions 031): `FPoolManager`
|
|
29
|
+
* holds the primitive and forwards every other selector from its fallback to `FPoolSponsor` —
|
|
30
|
+
* the lever, `claim`, `dissolve`, the handover, the gates, the desk, the names — by delegatecall.
|
|
31
|
+
* One address from outside, so one ABI here; both halves carry the base's events and errors,
|
|
32
|
+
* and viem tolerates the duplicates.
|
|
33
|
+
*/
|
|
34
|
+
export const fPoolManagerAbi = [...fPoolPrimitiveAbi, ...fPoolSponsorAbi];
|
|
27
35
|
const WAD = 10n ** 18n;
|
|
28
36
|
const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
29
37
|
/** Read a basket pool whole. Batched — viem multicalls these when the transport allows. */
|
|
@@ -57,11 +65,9 @@ export async function getFPool(c, poolId) {
|
|
|
57
65
|
]);
|
|
58
66
|
const bases = legs.map((l) => l[0]);
|
|
59
67
|
const weights = legs.map((l) => l[1]);
|
|
60
|
-
const x = legs.map((l) => l[2]);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const reserves = legs.map((l) => l[3]);
|
|
64
|
-
const { quote, Q, L, phi, theta0, bigSigma, authority, pendingAuthority, operator, minBuffer, gateMint, gateSwap, restructureBlock, feesOnly, seeded, dissolved } = p;
|
|
68
|
+
const x = legs.map((l) => l[2]); // derived by the manager: x_j = ln(w_j·L / R_j) (decisions 026)
|
|
69
|
+
const reserves = legs.map((l) => l[3]); // the state
|
|
70
|
+
const { quote, Q, L, phi, theta0, bigSigma, authority, pendingAuthority, operator, minBuffer, gateMint, gateSwap, restructureBlock, lockStrike, seeded, gen } = p;
|
|
65
71
|
const totalSupply = p.shares;
|
|
66
72
|
return {
|
|
67
73
|
poolId,
|
|
@@ -84,9 +90,9 @@ export async function getFPool(c, poolId) {
|
|
|
84
90
|
gateMint,
|
|
85
91
|
gateSwap,
|
|
86
92
|
restructureBlock: Number(restructureBlock),
|
|
87
|
-
|
|
93
|
+
lockStrike,
|
|
88
94
|
seeded,
|
|
89
|
-
|
|
95
|
+
gen: Number(gen),
|
|
90
96
|
totalSupply,
|
|
91
97
|
reserves,
|
|
92
98
|
};
|
|
@@ -200,14 +206,69 @@ export async function fPoolZapOut(c, a) {
|
|
|
200
206
|
const to = a.to ?? a.account;
|
|
201
207
|
return writeRouter(c, "zapOut", [a.poolId, a.shares, a.tokenOut, a.minOut ?? 0n, to, a.deadline ?? defaultDeadline()], a.account);
|
|
202
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Roll a retired generation's bundle into the pool's live one (decisions 025, 032), on the
|
|
211
|
+
* router under one lock: redeem `shares` of generation `gen` in place — the legs, the quote and
|
|
212
|
+
* any unpulled dividend come back — buy through the pool's own curve only what the live
|
|
213
|
+
* generation's ratio lacks, mint `dL` of it to `to`, and refund the rest in kind. Quote the
|
|
214
|
+
* bundle does not cover is pulled from the payer, at most `maxQuoteIn`; surplus base is
|
|
215
|
+
* refunded, never sold. Size `dL` with {@link fPoolPreviewRollIn}. The router must be the
|
|
216
|
+
* caller's ERC-6909 operator ({@link approveRouterForFPool}).
|
|
217
|
+
*/
|
|
218
|
+
export async function fPoolRollIn(c, a) {
|
|
219
|
+
const to = a.to ?? a.account;
|
|
220
|
+
return writeRouter(c, "rollIn", [a.poolId, BigInt(a.gen), a.shares, a.dL, a.maxQuoteIn ?? 0n, a.minShares ?? 0n, to, a.deadline ?? defaultDeadline()], a.account);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* The roll `holder`'s `shares` of retired generation `gen` fund into the live one WITHOUT a
|
|
224
|
+
* trade: the largest `dL` the bundle's base covers on every leg, and the quote the bundle is
|
|
225
|
+
* short of (pass it as `maxQuoteIn`) or over (refunded — the up direction's distribution) at
|
|
226
|
+
* that `dL`. A leg the live generation admitted since makes `dL` zero: such a roll must buy, so
|
|
227
|
+
* size it below with `previewZapIn` in mind. Zero for the live generation, or before the next
|
|
228
|
+
* seed.
|
|
229
|
+
*/
|
|
230
|
+
export async function fPoolPreviewRollIn(c, poolId, gen, holder, shares) {
|
|
231
|
+
const { logswapLensAbi } = await import("./generated.js");
|
|
232
|
+
const [dL, quoteShort, quoteExcess] = (await c.public.readContract({
|
|
233
|
+
address: c.addresses.lens,
|
|
234
|
+
abi: logswapLensAbi,
|
|
235
|
+
functionName: "previewRollIn",
|
|
236
|
+
args: [poolId, BigInt(gen), holder, shares],
|
|
237
|
+
}));
|
|
238
|
+
return { dL, quoteShort, quoteExcess };
|
|
239
|
+
}
|
|
203
240
|
// ─── the floor lever (authority only) ─────────────────────────────────────────
|
|
204
241
|
/**
|
|
205
|
-
* Remove quote, lifting θ — price-neutral,
|
|
206
|
-
*
|
|
242
|
+
* Remove quote, lifting θ — price-neutral, no base moves, and since decisions 028 a DIVIDEND to
|
|
243
|
+
* every share: the amount goes into the pool's pot and each holder's slice is settled lazily on
|
|
244
|
+
* their next transfer, mint or burn, or pulled with {@link fPoolClaim}. The sponsor's own slice —
|
|
245
|
+
* its shares' and the locked seed's at 0xdead — is pushed to `to` at once. Under `lockStrike`
|
|
246
|
+
* the lift stops at θ₀ (income only); on every live pool it stops at `LEVER_FLOOR` (Q/L ≥ ln 1.25).
|
|
207
247
|
*/
|
|
208
248
|
export async function fPoolHarvest(c, a) {
|
|
209
249
|
return writeFPool(c, a.poolId, "harvest", [a.amount, a.to ?? a.account], a.account);
|
|
210
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Pull one's settled dividend (decisions 028) on a generation's shares without moving them;
|
|
253
|
+
* anyone with shares. `gen` defaults to the live generation; a retired generation's harvests
|
|
254
|
+
* stay claimable under its own id (decisions 032).
|
|
255
|
+
*/
|
|
256
|
+
export async function fPoolClaim(c, a) {
|
|
257
|
+
const gen = a.gen ?? (await fPoolGen(c, a.poolId));
|
|
258
|
+
return writeFPool(c, a.poolId, "claim", [BigInt(gen), a.to ?? a.account], a.account);
|
|
259
|
+
}
|
|
260
|
+
/** A holder's dividend as of now on generation `gen` (the live one by default) — banked plus pending on the current balance (decisions 028). */
|
|
261
|
+
export async function fPoolDividendOf(c, poolId, holder, gen) {
|
|
262
|
+
const g = gen ?? (await fPoolGen(c, poolId));
|
|
263
|
+
return c.public.readContract({
|
|
264
|
+
address: c.addresses.fPoolManager,
|
|
265
|
+
abi: fPoolManagerAbi,
|
|
266
|
+
functionName: "dividendOf",
|
|
267
|
+
args: [poolId, BigInt(g), holder],
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
/** The lever's floor: `harvest` may not take Q/L under ln 1.25 — the floor stays ≥ 20% below the mark (decisions 025). */
|
|
271
|
+
export const LEVER_FLOOR = 223143551314209755n;
|
|
211
272
|
/** 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. */
|
|
212
273
|
export async function fPoolDeepen(c, a) {
|
|
213
274
|
return writeFPool(c, a.poolId, "deepen", [a.amount], a.account);
|
|
@@ -235,6 +296,18 @@ async function writeFPool(c, poolId, functionName, args, account) {
|
|
|
235
296
|
});
|
|
236
297
|
return wallet.writeContract(request);
|
|
237
298
|
}
|
|
299
|
+
/** A manager write that is NOT keyed by a poolId — `multicall`. */
|
|
300
|
+
async function writeFPool0(c, functionName, args, account) {
|
|
301
|
+
const wallet = requireWallet(c);
|
|
302
|
+
const { request } = await c.public.simulateContract({
|
|
303
|
+
address: c.addresses.fPoolManager,
|
|
304
|
+
abi: fPoolManagerAbi,
|
|
305
|
+
functionName,
|
|
306
|
+
args,
|
|
307
|
+
account,
|
|
308
|
+
});
|
|
309
|
+
return wallet.writeContract(request);
|
|
310
|
+
}
|
|
238
311
|
async function writeRouter(c, functionName, args, account,
|
|
239
312
|
/** Tokens the call pulls: missing Permit2 allowances are SIGNED and ride in the same tx. */
|
|
240
313
|
pullTokens = []) {
|
|
@@ -320,22 +393,71 @@ export async function approveRouterForFPool(c, account) {
|
|
|
320
393
|
// One ERC-6909 space, split structurally on bit 255 — the C manager's scheme. Derived here rather
|
|
321
394
|
// than read from the chain: it is pure, and a client that has to call to learn an id cannot build
|
|
322
395
|
// a multicall that uses it.
|
|
323
|
-
/**
|
|
324
|
-
|
|
325
|
-
|
|
396
|
+
/**
|
|
397
|
+
* The ERC-6909 id carrying generation `gen` of a pool's shares (decisions 032): bit 255 set (the
|
|
398
|
+
* share flag), the pool id's top 239 bits, the generation in the low 16. Each generation's shares
|
|
399
|
+
* are their own asset — a retired one is a claim on its bundle, the live one on the pool.
|
|
400
|
+
*/
|
|
401
|
+
export function fPoolShareId(poolId, gen = 0n) {
|
|
402
|
+
return (1n << 255n) | ((BigInt(poolId) >> 17n) << 16n) | BigInt(gen);
|
|
403
|
+
}
|
|
404
|
+
/** The generation a share id carries — its low 16 bits. */
|
|
405
|
+
export function fPoolGenOfShareId(id) {
|
|
406
|
+
return Number(id & 0xffffn);
|
|
407
|
+
}
|
|
408
|
+
/** The pool's live generation, one read. */
|
|
409
|
+
export async function fPoolGen(c, poolId) {
|
|
410
|
+
const p = (await c.public.readContract({
|
|
411
|
+
address: c.addresses.fPoolManager,
|
|
412
|
+
abi: fPoolManagerAbi,
|
|
413
|
+
functionName: "getPool",
|
|
414
|
+
args: [poolId],
|
|
415
|
+
}));
|
|
416
|
+
return Number(p.gen);
|
|
326
417
|
}
|
|
327
418
|
/** The ERC-6909 id carrying claims on a token. Bit 255 clear, so it can never meet a share id. */
|
|
328
419
|
export function fPoolClaimId(token) {
|
|
329
420
|
return BigInt(token);
|
|
330
421
|
}
|
|
331
|
-
|
|
422
|
+
/** A holder's shares of generation `gen` — the live one by default. */
|
|
423
|
+
export async function fPoolShareBalance(c, poolId, owner, gen) {
|
|
424
|
+
const g = gen ?? (await fPoolGen(c, poolId));
|
|
332
425
|
return c.public.readContract({
|
|
333
426
|
address: c.addresses.fPoolManager,
|
|
334
427
|
abi: fPoolManagerAbi,
|
|
335
428
|
functionName: "balanceOf",
|
|
336
|
-
args: [owner, fPoolShareId(poolId)],
|
|
429
|
+
args: [owner, fPoolShareId(poolId, g)],
|
|
337
430
|
});
|
|
338
431
|
}
|
|
432
|
+
/** A retired generation's bundle (decisions 032): what is left to redeem — supply, quote, base per leg index. */
|
|
433
|
+
export async function fPoolBundleOf(c, poolId, gen) {
|
|
434
|
+
const [supply, quote, base] = (await c.public.readContract({
|
|
435
|
+
address: c.addresses.fPoolManager,
|
|
436
|
+
abi: fPoolManagerAbi,
|
|
437
|
+
functionName: "bundleOf",
|
|
438
|
+
args: [poolId, BigInt(gen)],
|
|
439
|
+
}));
|
|
440
|
+
return { supply, quote, base: [...base] };
|
|
441
|
+
}
|
|
442
|
+
/** A holder's claims on a pool's retired generations — one row per generation still held (decisions 032). */
|
|
443
|
+
export async function fPoolClaimsOf(c, poolId, owner) {
|
|
444
|
+
const { logswapLensAbi } = await import("./generated.js");
|
|
445
|
+
const rows = (await c.public.readContract({
|
|
446
|
+
address: c.addresses.lens,
|
|
447
|
+
abi: logswapLensAbi,
|
|
448
|
+
functionName: "fClaimsOf",
|
|
449
|
+
args: [poolId, owner],
|
|
450
|
+
}));
|
|
451
|
+
return rows.map((r) => ({ gen: Number(r.gen), shares: r.shares, base: [...r.base], quote: r.quote, dividend: r.dividend }));
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Redeem `shares` of a RETIRED generation (decisions 032): its bundle, pro rata — the base per
|
|
455
|
+
* leg and the quote — plus the owner's settled dividend. Not `burn`: nothing can move a bundle's
|
|
456
|
+
* ratio, so there is no slippage to bound. The owner, or an operator of theirs.
|
|
457
|
+
*/
|
|
458
|
+
export async function fPoolRedeem(c, a) {
|
|
459
|
+
return writeFPool(c, a.poolId, "redeem", [BigInt(a.gen), a.owner ?? a.account, a.shares], a.account);
|
|
460
|
+
}
|
|
339
461
|
export async function fPoolClaimBalance(c, token, owner) {
|
|
340
462
|
return c.public.readContract({
|
|
341
463
|
address: c.addresses.fPoolManager,
|
|
@@ -433,7 +555,7 @@ export async function fPoolInitialize(c, a) {
|
|
|
433
555
|
if (sum !== 10n ** 18n)
|
|
434
556
|
throw new Error(`logswap: weights sum to ${sum}, expected 1e18`);
|
|
435
557
|
const { bases, companions } = sortFPoolLegs(a.bases, a.weights);
|
|
436
|
-
const key = { quote: a.quote, bases, weights: companions[0], phi: a.phi,
|
|
558
|
+
const key = { quote: a.quote, bases, weights: companions[0], phi: a.phi, lockStrike: a.lockStrike, authority: a.authority, salt: a.salt ?? ZERO_SALT };
|
|
437
559
|
const wallet = requireWallet(c);
|
|
438
560
|
const { request } = await c.public.simulateContract({
|
|
439
561
|
address: c.addresses.fPoolManager,
|
|
@@ -447,7 +569,7 @@ export async function fPoolInitialize(c, a) {
|
|
|
447
569
|
/** The pool id is the key's hash — pure, so it can be read before or after creation. */
|
|
448
570
|
export async function fPoolIdOf(c, a) {
|
|
449
571
|
const { bases, companions } = sortFPoolLegs(a.bases, a.weights);
|
|
450
|
-
const key = { quote: a.quote, bases, weights: companions[0], phi: a.phi,
|
|
572
|
+
const key = { quote: a.quote, bases, weights: companions[0], phi: a.phi, lockStrike: a.lockStrike, authority: a.authority, salt: a.salt ?? ZERO_SALT };
|
|
451
573
|
return c.public.readContract({
|
|
452
574
|
address: c.addresses.fPoolManager,
|
|
453
575
|
abi: fPoolManagerAbi,
|
|
@@ -456,17 +578,57 @@ export async function fPoolIdOf(c, a) {
|
|
|
456
578
|
});
|
|
457
579
|
}
|
|
458
580
|
/**
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
581
|
+
* The reserve a leg holds at a mark: `R = Lj·e^{−x}`, WAD math. The seed names RESERVES since
|
|
582
|
+
* decisions 029 — the sponsor states holdings and the price follows, `p = Lj / R` — so this is
|
|
583
|
+
* the one conversion from a price to what the pool will hold, done here, on the way in. Float
|
|
584
|
+
* precision (~1e-16 relative) is what a seed needs: any reserve is a legal seed, and the mark
|
|
585
|
+
* the pool derives from it is the one the sponsor meant to within that.
|
|
586
|
+
*/
|
|
587
|
+
export function fPoolReserveAt(Lj, x) {
|
|
588
|
+
const e = Math.exp(-Number(x) / 1e18);
|
|
589
|
+
return (Lj * BigInt(Math.round(e * 1e18))) / 10n ** 18n;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Arm the pool: deposit `r0[j]` of each base plus `Q0` of quote against exposure `L0`. Pass either
|
|
593
|
+
* the reserves outright (`r0`) or the marks the pool should open at (`x0`, converted here with
|
|
594
|
+
* {@link fPoolReserveAt} against the key's weights). Authority-only on-chain (an open seed lets
|
|
595
|
+
* anyone front-run the creator for the strike). Arrays align with the SORTED bases — use
|
|
596
|
+
* {@link sortFPoolLegs} on (bases, weights, x0) together when building forms.
|
|
462
597
|
*/
|
|
463
598
|
export async function fPoolSeed(c, a) {
|
|
464
|
-
|
|
599
|
+
const r0 = "r0" in a ? a.r0 : a.x0.map((x, j) => fPoolReserveAt((a.weights[j] * a.L0) / 10n ** 18n, x));
|
|
600
|
+
return writeFPool(c, a.poolId, "seed", [a.L0, r0, a.Q0], a.account);
|
|
465
601
|
}
|
|
466
|
-
/**
|
|
602
|
+
/**
|
|
603
|
+
* Retire the live generation (decisions 025, 032). Allowed at Q ≤ L/1e9 on every pool — the
|
|
604
|
+
* market filled the ask — and on a pool that is not strike-locked at any Q. The live (S, Q, R_j)
|
|
605
|
+
* become a frozen bundle every share of this generation redeems ({@link fPoolRedeem}) or rolls
|
|
606
|
+
* ({@link fPoolRollIn}), forever; the pool is unseeded until the next {@link fPoolSeed}, which
|
|
607
|
+
* opens generation `gen + 1` under the same id, gates, lists and promises.
|
|
608
|
+
*/
|
|
467
609
|
export async function fPoolDissolve(c, a) {
|
|
468
610
|
return writeFPool(c, a.poolId, "dissolve", [], a.account);
|
|
469
611
|
}
|
|
612
|
+
/**
|
|
613
|
+
* The sponsor's relaunch as ONE transaction (decisions 025, 032): `dissolve` the live generation,
|
|
614
|
+
* `redeem` the sponsor's own shares of it (when `shares` > 0), `seed` the next generation with
|
|
615
|
+
* what came back — the manager's `multicall`, the sponsor as sender throughout, the same pool.
|
|
616
|
+
* Gates, allowlist, operator, `minBuffer` and names carry over; anything else goes in `extra`,
|
|
617
|
+
* pre-encoded against {@link fPoolManagerAbi}. The seed names reserves (decisions 029): `r0`
|
|
618
|
+
* outright, or `x0` marks against the key's `weights`.
|
|
619
|
+
*/
|
|
620
|
+
export async function fPoolRelaunch(c, a) {
|
|
621
|
+
const gen = await fPoolGen(c, a.poolId);
|
|
622
|
+
const r0 = "r0" in a ? a.r0 : a.x0.map((x, j) => fPoolReserveAt((a.weights[j] * a.L0) / WAD, x));
|
|
623
|
+
const enc = (functionName, args) => encodeFunctionData({ abi: fPoolManagerAbi, functionName, args });
|
|
624
|
+
const calls = [
|
|
625
|
+
enc("dissolve", [a.poolId]),
|
|
626
|
+
...(a.shares > 0n ? [enc("redeem", [a.poolId, BigInt(gen), a.account, a.shares])] : []),
|
|
627
|
+
enc("seed", [a.poolId, a.L0, r0, a.Q0]),
|
|
628
|
+
...(a.extra ?? []),
|
|
629
|
+
];
|
|
630
|
+
return writeFPool0(c, "multicall", [calls], a.account);
|
|
631
|
+
}
|
|
470
632
|
/**
|
|
471
633
|
* Propose the next authority — step one of two (contracts `2aa6b7b`, decisions 020). Nothing moves
|
|
472
634
|
* until `next` accepts; proposing again (the zero address included) cancels a pending proposal.
|
|
@@ -480,8 +642,6 @@ export async function fPoolAcceptAuthority(c, a) {
|
|
|
480
642
|
return writeFPool(c, a.poolId, "acceptAuthority", [], a.account);
|
|
481
643
|
}
|
|
482
644
|
// ─── the sponsor's controls and the desk (contracts bd3dd87, decisions 021) ───────────────
|
|
483
|
-
/** `setLegL`'s "keep the stored mark" sentinel — the only legal `x` for a live leg. */
|
|
484
|
-
export const NO_X = -(2n ** 255n);
|
|
485
645
|
/** Turn the mint / swap gates on or off (authority). `burn` is never gated. */
|
|
486
646
|
export async function fPoolSetGates(c, a) {
|
|
487
647
|
return writeFPool(c, a.poolId, "setGates", [a.gateMint, a.gateSwap], a.account);
|
|
@@ -541,15 +701,17 @@ export async function fPoolRaiseMinBuffer(c, a) {
|
|
|
541
701
|
}
|
|
542
702
|
/**
|
|
543
703
|
* Set leg `j`'s liquidity (operator, sole LP only): grow, shrink, retire (`newLj = 0`), or re-admit
|
|
544
|
-
* a retired leg
|
|
545
|
-
*
|
|
704
|
+
* a retired leg holding `r` of the base (decisions 029 — the price follows, `p = newLj / r`; use
|
|
705
|
+
* {@link fPoolReserveAt} from a mark). For a live leg leave `r` undefined — its price is the
|
|
706
|
+
* market's, the reserve scales with the liquidity. Base moves single-sidedly through the lock;
|
|
707
|
+
* shares adjust to hold the share value.
|
|
546
708
|
*/
|
|
547
709
|
export async function fPoolSetLegL(c, a) {
|
|
548
|
-
return writeFPool(c, a.poolId, "setLegL", [BigInt(a.j), a.newLj, a.
|
|
710
|
+
return writeFPool(c, a.poolId, "setLegL", [BigInt(a.j), a.newLj, a.r ?? 0n], a.account);
|
|
549
711
|
}
|
|
550
|
-
/** Admit a base the pool has never held
|
|
712
|
+
/** Admit a base the pool has never held: `R` of it against liquidity `Lj`, so at `p = Lj / R` (operator, sole LP only). */
|
|
551
713
|
export async function fPoolAdmitLeg(c, a) {
|
|
552
|
-
return writeFPool(c, a.poolId, "admitLeg", [a.base, a.Lj, a.
|
|
714
|
+
return writeFPool(c, a.poolId, "admitLeg", [a.base, a.Lj, a.R], a.account);
|
|
553
715
|
}
|
|
554
716
|
/**
|
|
555
717
|
* Move shares (ERC-6909 `transfer`) — to another holder, or to `0xdead` to lock them for good.
|
|
@@ -558,18 +720,19 @@ export async function fPoolAdmitLeg(c, a) {
|
|
|
558
720
|
*/
|
|
559
721
|
export async function fPoolTransferShares(c, a) {
|
|
560
722
|
const wallet = requireWallet(c);
|
|
723
|
+
const gen = a.gen ?? (await fPoolGen(c, a.poolId));
|
|
561
724
|
const { request } = await c.public.simulateContract({
|
|
562
725
|
address: c.addresses.fPoolManager,
|
|
563
726
|
abi: fPoolManagerAbi,
|
|
564
727
|
functionName: "transfer",
|
|
565
|
-
args: [a.to, fPoolShareId(a.poolId), a.shares],
|
|
728
|
+
args: [a.to, fPoolShareId(a.poolId, gen), a.shares],
|
|
566
729
|
account: a.account,
|
|
567
730
|
});
|
|
568
731
|
return wallet.writeContract(request);
|
|
569
732
|
}
|
|
570
733
|
/**
|
|
571
734
|
* Every F pool ever created, from `Initialize` logs alone. Possible only because the event
|
|
572
|
-
* carries the full key preimage (bases, weights, phi,
|
|
735
|
+
* carries the full key preimage (bases, weights, phi, lockStrike) — the poolId is a hash and could
|
|
573
736
|
* never be inverted; contracts PR #17 exists for exactly this call.
|
|
574
737
|
*/
|
|
575
738
|
export async function discoverFPools(c, opts = {}) {
|
|
@@ -602,7 +765,7 @@ export async function discoverFPools(c, opts = {}) {
|
|
|
602
765
|
bases: [...a.bases],
|
|
603
766
|
weights: [...a.weights],
|
|
604
767
|
phi: a.phi,
|
|
605
|
-
|
|
768
|
+
lockStrike: a.lockStrike,
|
|
606
769
|
authority: a.authority,
|
|
607
770
|
block: l.blockNumber ?? 0n,
|
|
608
771
|
seeded: q0 !== undefined,
|
|
@@ -620,7 +783,7 @@ export async function fPoolShareHolders(c, poolIdHex, opts = {}) {
|
|
|
620
783
|
const ev = fPoolManagerAbi.find((x) => x.type === "event" && x.name === "Transfer");
|
|
621
784
|
if (!ev)
|
|
622
785
|
throw new Error("logswap: 6909 Transfer event missing from the generated ABI");
|
|
623
|
-
const id = fPoolShareId(poolIdHex);
|
|
786
|
+
const id = fPoolShareId(poolIdHex, opts.gen ?? (await fPoolGen(c, poolIdHex)));
|
|
624
787
|
const logs = await c.public.getLogs({
|
|
625
788
|
address: c.addresses.fPoolManager,
|
|
626
789
|
event: ev,
|
|
@@ -641,7 +804,7 @@ export async function fPoolShareHolders(c, poolIdHex, opts = {}) {
|
|
|
641
804
|
.map(([holder, shares]) => ({ holder: holder, shares }))
|
|
642
805
|
.sort((a, b) => (b.shares > a.shares ? 1 : -1));
|
|
643
806
|
}
|
|
644
|
-
/** Every F pool's state in one lens call (the raw manager struct: quote, phi, authority,
|
|
807
|
+
/** Every F pool's state in one lens call (the raw manager struct: quote, phi, authority, lockStrike, seeded, gen, n, Q, L, shares, theta0, bigSigma, leverTheta). */
|
|
645
808
|
export async function getFPoolsRaw(c, poolIds) {
|
|
646
809
|
const { logswapLensAbi } = await import("./generated.js");
|
|
647
810
|
return (await c.public.readContract({ address: c.addresses.lens, abi: logswapLensAbi, functionName: "getFPools", args: [poolIds] }));
|