@logswap/sdk 0.5.38 → 0.5.40
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/fpool.d.ts +78 -62
- package/dist/fpool.js +66 -5
- package/dist/generated.d.ts +2 -56
- package/dist/generated.js +2 -52
- package/package.json +1 -1
- package/src/fpool.ts +104 -7
- package/src/generated.ts +2 -52
package/dist/fpool.d.ts
CHANGED
|
@@ -464,7 +464,7 @@ export declare const fPoolManagerAbi: readonly [{
|
|
|
464
464
|
readonly internalType: "int256";
|
|
465
465
|
readonly type: "int256";
|
|
466
466
|
}, {
|
|
467
|
-
readonly name: "
|
|
467
|
+
readonly name: "harvestedTheta";
|
|
468
468
|
readonly internalType: "int256";
|
|
469
469
|
readonly type: "int256";
|
|
470
470
|
}, {
|
|
@@ -1357,26 +1357,6 @@ export declare const fPoolManagerAbi: readonly [{
|
|
|
1357
1357
|
readonly indexed: true;
|
|
1358
1358
|
}];
|
|
1359
1359
|
readonly name: "CollectorProposed";
|
|
1360
|
-
}, {
|
|
1361
|
-
readonly type: "event";
|
|
1362
|
-
readonly anonymous: false;
|
|
1363
|
-
readonly inputs: readonly [{
|
|
1364
|
-
readonly name: "poolId";
|
|
1365
|
-
readonly internalType: "bytes32";
|
|
1366
|
-
readonly type: "bytes32";
|
|
1367
|
-
readonly indexed: true;
|
|
1368
|
-
}, {
|
|
1369
|
-
readonly name: "from";
|
|
1370
|
-
readonly internalType: "address";
|
|
1371
|
-
readonly type: "address";
|
|
1372
|
-
readonly indexed: true;
|
|
1373
|
-
}, {
|
|
1374
|
-
readonly name: "amount";
|
|
1375
|
-
readonly internalType: "uint256";
|
|
1376
|
-
readonly type: "uint256";
|
|
1377
|
-
readonly indexed: false;
|
|
1378
|
-
}];
|
|
1379
|
-
readonly name: "Deepen";
|
|
1380
1360
|
}, {
|
|
1381
1361
|
readonly type: "event";
|
|
1382
1362
|
readonly anonymous: false;
|
|
@@ -2343,20 +2323,6 @@ export declare const fPoolManagerAbi: readonly [{
|
|
|
2343
2323
|
readonly type: "uint8";
|
|
2344
2324
|
}];
|
|
2345
2325
|
readonly stateMutability: "view";
|
|
2346
|
-
}, {
|
|
2347
|
-
readonly type: "function";
|
|
2348
|
-
readonly inputs: readonly [{
|
|
2349
|
-
readonly name: "poolId";
|
|
2350
|
-
readonly internalType: "bytes32";
|
|
2351
|
-
readonly type: "bytes32";
|
|
2352
|
-
}, {
|
|
2353
|
-
readonly name: "amount";
|
|
2354
|
-
readonly internalType: "uint256";
|
|
2355
|
-
readonly type: "uint256";
|
|
2356
|
-
}];
|
|
2357
|
-
readonly name: "deepen";
|
|
2358
|
-
readonly outputs: readonly [];
|
|
2359
|
-
readonly stateMutability: "nonpayable";
|
|
2360
2326
|
}, {
|
|
2361
2327
|
readonly type: "function";
|
|
2362
2328
|
readonly inputs: readonly [{
|
|
@@ -3070,26 +3036,6 @@ export declare const fPoolManagerAbi: readonly [{
|
|
|
3070
3036
|
readonly indexed: true;
|
|
3071
3037
|
}];
|
|
3072
3038
|
readonly name: "CollectorProposed";
|
|
3073
|
-
}, {
|
|
3074
|
-
readonly type: "event";
|
|
3075
|
-
readonly anonymous: false;
|
|
3076
|
-
readonly inputs: readonly [{
|
|
3077
|
-
readonly name: "poolId";
|
|
3078
|
-
readonly internalType: "bytes32";
|
|
3079
|
-
readonly type: "bytes32";
|
|
3080
|
-
readonly indexed: true;
|
|
3081
|
-
}, {
|
|
3082
|
-
readonly name: "from";
|
|
3083
|
-
readonly internalType: "address";
|
|
3084
|
-
readonly type: "address";
|
|
3085
|
-
readonly indexed: true;
|
|
3086
|
-
}, {
|
|
3087
|
-
readonly name: "amount";
|
|
3088
|
-
readonly internalType: "uint256";
|
|
3089
|
-
readonly type: "uint256";
|
|
3090
|
-
readonly indexed: false;
|
|
3091
|
-
}];
|
|
3092
|
-
readonly name: "Deepen";
|
|
3093
3039
|
}, {
|
|
3094
3040
|
readonly type: "event";
|
|
3095
3041
|
readonly anonymous: false;
|
|
@@ -3963,12 +3909,6 @@ export declare function fPoolClaim(c: LogswapClient, a: {
|
|
|
3963
3909
|
export declare function fPoolDividendOf(c: LogswapClient, poolId: Hex, holder: Address, gen?: bigint | number): Promise<bigint>;
|
|
3964
3910
|
/** The lever's floor: `harvest` may not take Q/L under ln 1.25 — the floor stays ≥ 20% below the mark (decisions 025). */
|
|
3965
3911
|
export declare const LEVER_FLOOR = 223143551314209755n;
|
|
3966
|
-
/** 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. */
|
|
3967
|
-
export declare function fPoolDeepen(c: LogswapClient, a: {
|
|
3968
|
-
poolId: Hex;
|
|
3969
|
-
amount: bigint;
|
|
3970
|
-
account: Address;
|
|
3971
|
-
}): Promise<`0x${string}`>;
|
|
3972
3912
|
/** Plain ERC-20 approval to the F manager — the allowance every DIRECT call pulls against. */
|
|
3973
3913
|
export declare function approveTokenForFPoolManager(c: LogswapClient, token: Address): Promise<Hash>;
|
|
3974
3914
|
/** Does `owner` have enough allowance on `token` for the MANAGER to pull `need`? */
|
|
@@ -4131,6 +4071,82 @@ export declare function fPoolRelaunch(c: LogswapClient, a: {
|
|
|
4131
4071
|
x0: bigint[];
|
|
4132
4072
|
weights: bigint[];
|
|
4133
4073
|
})): Promise<`0x${string}`>;
|
|
4074
|
+
/** ERC-6909 shares sent here are locked for good — the seed's custody (custody.md §4(b)). */
|
|
4075
|
+
export declare const DEAD_ADDRESS: Address;
|
|
4076
|
+
/** The manager's `MIN_SHARES`: the seed mints this much to 0xdead itself, the rest to the seeder. */
|
|
4077
|
+
export declare const F_MIN_SHARES = 1000n;
|
|
4078
|
+
export interface FPoolLaunchArgs extends Omit<FPoolCreateArgs, "account"> {
|
|
4079
|
+
L0: bigint;
|
|
4080
|
+
/** Quote the seed pulls. A pad seeds at 0 — pure float, a resting ask, nothing raised. */
|
|
4081
|
+
Q0: bigint;
|
|
4082
|
+
/**
|
|
4083
|
+
* Send every share the seed mints to the creator (`L0 − MIN_SHARES`) to 0xdead in the same
|
|
4084
|
+
* batch: the float and the raise can never be burned out from under the buyers. The lever
|
|
4085
|
+
* (harvest) is the authority's and survives it; the exit does not. A pad's default posture.
|
|
4086
|
+
*/
|
|
4087
|
+
lockSeed?: boolean;
|
|
4088
|
+
/**
|
|
4089
|
+
* An opening buy of leg `j` (an index into `bases` AS GIVEN) for `amountIn` of quote, ON THE
|
|
4090
|
+
* MANAGER — the same sender, a plain allowance to the manager, the router nowhere near it. A
|
|
4091
|
+
* pad seeds at Q = 0, so until someone trades it the mark sits at p₀; buying inside the launch
|
|
4092
|
+
* gives it a price that has moved and a buffer under it. Nothing can trade between the seed and
|
|
4093
|
+
* this buy — they are one transaction — so `minOut` is safe at its default of 0.
|
|
4094
|
+
*/
|
|
4095
|
+
openBuy?: {
|
|
4096
|
+
j: number;
|
|
4097
|
+
amountIn: bigint;
|
|
4098
|
+
minOut?: bigint;
|
|
4099
|
+
};
|
|
4100
|
+
/** The pool's label, set in the batch (≤ 31 bytes of UTF-8). */
|
|
4101
|
+
name?: string;
|
|
4102
|
+
/** Gate minting, list the creator, appoint them operator (decisions 021) — three calls, in the batch. */
|
|
4103
|
+
privatePool?: boolean;
|
|
4104
|
+
/**
|
|
4105
|
+
* The pool already exists (a previous launch got as far as `initialize` and no further — a seed
|
|
4106
|
+
* that reverted, a closed tab, before the launch was one transaction), so `initialize` is left
|
|
4107
|
+
* out: the key is a pure function of the arguments and a second `initialize` can only revert.
|
|
4108
|
+
*/
|
|
4109
|
+
initialized?: boolean;
|
|
4110
|
+
/** Anything else, pre-encoded against {@link fPoolManagerAbi}, appended after the above. */
|
|
4111
|
+
extra?: Hex[];
|
|
4112
|
+
account: Address;
|
|
4113
|
+
}
|
|
4114
|
+
/**
|
|
4115
|
+
* The launch's calls, in order — the batch {@link fPoolLaunch} sends. Pure, so a form can show
|
|
4116
|
+
* what it is about to send, and a test can decode it. Legs are sorted here with their weights and
|
|
4117
|
+
* reserves (the key's canonical order; `openBuy.j` is re-indexed to match), and the weights are
|
|
4118
|
+
* checked here, where the message is readable.
|
|
4119
|
+
*/
|
|
4120
|
+
export declare function fPoolLaunchCalls(poolId: Hex, a: FPoolLaunchArgs & ({
|
|
4121
|
+
r0: bigint[];
|
|
4122
|
+
} | {
|
|
4123
|
+
x0: bigint[];
|
|
4124
|
+
})): Hex[];
|
|
4125
|
+
/**
|
|
4126
|
+
* Create a pool as ONE transaction: `initialize`, `seed`, the seed lock, the opening buy, the
|
|
4127
|
+
* name, the private-pool gates — the manager's `multicall`, the creator as sender throughout.
|
|
4128
|
+
* Either every call lands or none does; there is no half-built pool to resume.
|
|
4129
|
+
*
|
|
4130
|
+
* Why the manager and not the router: every one of these entries authenticates by `msg.sender`
|
|
4131
|
+
* (`seed` is authority-only, so is everything after it). Routed, the router would be the sender
|
|
4132
|
+
* — the authority, the holder of the seed shares — and the handover back is two-step, so it
|
|
4133
|
+
* could not even close in the same transaction. `multicall` is delegatecall-to-self, so the
|
|
4134
|
+
* sender survives, which is what the manager's own doc says a router cannot do.
|
|
4135
|
+
*
|
|
4136
|
+
* What the batch PULLS, by plain allowance to the manager (never Permit2): `r0[j]` of each base,
|
|
4137
|
+
* `Q0` of quote, plus `openBuy.amountIn` of quote. Grant those first — one `approve` per token,
|
|
4138
|
+
* once ever ({@link approveTokenForFPoolManager}, {@link fPoolManagerAllowanceOk}).
|
|
4139
|
+
*
|
|
4140
|
+
* Returns the hash and the pool's id (the key's hash, {@link fPoolIdOf}).
|
|
4141
|
+
*/
|
|
4142
|
+
export declare function fPoolLaunch(c: LogswapClient, a: FPoolLaunchArgs & ({
|
|
4143
|
+
r0: bigint[];
|
|
4144
|
+
} | {
|
|
4145
|
+
x0: bigint[];
|
|
4146
|
+
})): Promise<{
|
|
4147
|
+
hash: Hash;
|
|
4148
|
+
poolId: Hex;
|
|
4149
|
+
}>;
|
|
4134
4150
|
/**
|
|
4135
4151
|
* Propose the next authority — step one of two (contracts `2aa6b7b`, decisions 020). Nothing moves
|
|
4136
4152
|
* until `next` accepts; proposing again (the zero address included) cancels a pending proposal.
|
|
@@ -4271,7 +4287,7 @@ export declare function fPoolShareHolders(c: LogswapClient, poolIdHex: Hex, opts
|
|
|
4271
4287
|
holder: Address;
|
|
4272
4288
|
shares: bigint;
|
|
4273
4289
|
}>>;
|
|
4274
|
-
/** 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,
|
|
4290
|
+
/** 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, harvestedTheta). */
|
|
4275
4291
|
export declare function getFPoolsRaw(c: LogswapClient, poolIds: Hex[]): Promise<readonly unknown[]>;
|
|
4276
4292
|
/** Share value from the lens — (L + Q)/shares, WAD per share — the same figure as `fPoolShareValue`, from one source. */
|
|
4277
4293
|
export declare function shareValueOnChain(c: LogswapClient, poolId: Hex): Promise<bigint>;
|
package/dist/fpool.js
CHANGED
|
@@ -269,10 +269,6 @@ export async function fPoolDividendOf(c, poolId, holder, gen) {
|
|
|
269
269
|
}
|
|
270
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
271
|
export const LEVER_FLOOR = 223143551314209755n;
|
|
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. */
|
|
273
|
-
export async function fPoolDeepen(c, a) {
|
|
274
|
-
return writeFPool(c, a.poolId, "deepen", [a.amount], a.account);
|
|
275
|
-
}
|
|
276
272
|
// ─── internals ────────────────────────────────────────────────────────────────
|
|
277
273
|
function defaultDeadline() {
|
|
278
274
|
return BigInt(Math.floor(Date.now() / 1000) + 1800);
|
|
@@ -629,6 +625,71 @@ export async function fPoolRelaunch(c, a) {
|
|
|
629
625
|
];
|
|
630
626
|
return writeFPool0(c, "multicall", [calls], a.account);
|
|
631
627
|
}
|
|
628
|
+
/** ERC-6909 shares sent here are locked for good — the seed's custody (custody.md §4(b)). */
|
|
629
|
+
export const DEAD_ADDRESS = "0x000000000000000000000000000000000000dEaD";
|
|
630
|
+
/** The manager's `MIN_SHARES`: the seed mints this much to 0xdead itself, the rest to the seeder. */
|
|
631
|
+
export const F_MIN_SHARES = 1000n;
|
|
632
|
+
/**
|
|
633
|
+
* The launch's calls, in order — the batch {@link fPoolLaunch} sends. Pure, so a form can show
|
|
634
|
+
* what it is about to send, and a test can decode it. Legs are sorted here with their weights and
|
|
635
|
+
* reserves (the key's canonical order; `openBuy.j` is re-indexed to match), and the weights are
|
|
636
|
+
* checked here, where the message is readable.
|
|
637
|
+
*/
|
|
638
|
+
export function fPoolLaunchCalls(poolId, a) {
|
|
639
|
+
const sum = a.weights.reduce((x, y) => x + y, 0n);
|
|
640
|
+
if (sum !== WAD)
|
|
641
|
+
throw new Error(`logswap: weights sum to ${sum}, expected 1e18`);
|
|
642
|
+
const given = "r0" in a ? a.r0 : a.x0.map((x, j) => fPoolReserveAt((a.weights[j] * a.L0) / WAD, x));
|
|
643
|
+
if (given.length !== a.bases.length)
|
|
644
|
+
throw new Error(`logswap: ${given.length} reserves for ${a.bases.length} legs`);
|
|
645
|
+
const { bases, companions } = sortFPoolLegs(a.bases, a.weights, given);
|
|
646
|
+
const key = { quote: a.quote, bases, weights: companions[0], phi: a.phi, lockStrike: a.lockStrike, authority: a.authority, salt: a.salt ?? ZERO_SALT };
|
|
647
|
+
const enc = (functionName, args) => encodeFunctionData({ abi: fPoolManagerAbi, functionName, args });
|
|
648
|
+
const calls = [];
|
|
649
|
+
if (!a.initialized)
|
|
650
|
+
calls.push(enc("initialize", [key]));
|
|
651
|
+
calls.push(enc("seed", [poolId, a.L0, companions[1], a.Q0]));
|
|
652
|
+
// gen 0 by construction: a launch is the pool's FIRST seed — a relaunch is `fPoolRelaunch`
|
|
653
|
+
if (a.lockSeed)
|
|
654
|
+
calls.push(enc("transfer", [DEAD_ADDRESS, fPoolShareId(poolId, 0), a.L0 - F_MIN_SHARES]));
|
|
655
|
+
if (a.openBuy) {
|
|
656
|
+
const j = bases.indexOf(a.bases[a.openBuy.j]);
|
|
657
|
+
if (j < 0)
|
|
658
|
+
throw new Error(`logswap: openBuy.j = ${a.openBuy.j} is not a leg`);
|
|
659
|
+
calls.push(enc("swapQuoteIn", [poolId, BigInt(j), a.openBuy.amountIn, a.openBuy.minOut ?? 0n, a.account]));
|
|
660
|
+
}
|
|
661
|
+
if (a.name)
|
|
662
|
+
calls.push(enc("setName", [poolId, textToBytes32(a.name)]));
|
|
663
|
+
if (a.privatePool) {
|
|
664
|
+
calls.push(enc("setGates", [poolId, true, false]));
|
|
665
|
+
calls.push(enc("setAllowed", [poolId, [a.account], true]));
|
|
666
|
+
calls.push(enc("appointOperator", [poolId, a.account]));
|
|
667
|
+
}
|
|
668
|
+
calls.push(...(a.extra ?? []));
|
|
669
|
+
return calls;
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* Create a pool as ONE transaction: `initialize`, `seed`, the seed lock, the opening buy, the
|
|
673
|
+
* name, the private-pool gates — the manager's `multicall`, the creator as sender throughout.
|
|
674
|
+
* Either every call lands or none does; there is no half-built pool to resume.
|
|
675
|
+
*
|
|
676
|
+
* Why the manager and not the router: every one of these entries authenticates by `msg.sender`
|
|
677
|
+
* (`seed` is authority-only, so is everything after it). Routed, the router would be the sender
|
|
678
|
+
* — the authority, the holder of the seed shares — and the handover back is two-step, so it
|
|
679
|
+
* could not even close in the same transaction. `multicall` is delegatecall-to-self, so the
|
|
680
|
+
* sender survives, which is what the manager's own doc says a router cannot do.
|
|
681
|
+
*
|
|
682
|
+
* What the batch PULLS, by plain allowance to the manager (never Permit2): `r0[j]` of each base,
|
|
683
|
+
* `Q0` of quote, plus `openBuy.amountIn` of quote. Grant those first — one `approve` per token,
|
|
684
|
+
* once ever ({@link approveTokenForFPoolManager}, {@link fPoolManagerAllowanceOk}).
|
|
685
|
+
*
|
|
686
|
+
* Returns the hash and the pool's id (the key's hash, {@link fPoolIdOf}).
|
|
687
|
+
*/
|
|
688
|
+
export async function fPoolLaunch(c, a) {
|
|
689
|
+
const poolId = await fPoolIdOf(c, a);
|
|
690
|
+
const hash = await writeFPool0(c, "multicall", [fPoolLaunchCalls(poolId, a)], a.account);
|
|
691
|
+
return { hash, poolId };
|
|
692
|
+
}
|
|
632
693
|
/**
|
|
633
694
|
* Propose the next authority — step one of two (contracts `2aa6b7b`, decisions 020). Nothing moves
|
|
634
695
|
* until `next` accepts; proposing again (the zero address included) cancels a pending proposal.
|
|
@@ -804,7 +865,7 @@ export async function fPoolShareHolders(c, poolIdHex, opts = {}) {
|
|
|
804
865
|
.map(([holder, shares]) => ({ holder: holder, shares }))
|
|
805
866
|
.sort((a, b) => (b.shares > a.shares ? 1 : -1));
|
|
806
867
|
}
|
|
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,
|
|
868
|
+
/** 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, harvestedTheta). */
|
|
808
869
|
export async function getFPoolsRaw(c, poolIds) {
|
|
809
870
|
const { logswapLensAbi } = await import("./generated.js");
|
|
810
871
|
return (await c.public.readContract({ address: c.addresses.lens, abi: logswapLensAbi, functionName: "getFPools", args: [poolIds] }));
|
package/dist/generated.d.ts
CHANGED
|
@@ -2223,7 +2223,7 @@ export declare const fPoolManagerAbi: readonly [{
|
|
|
2223
2223
|
readonly internalType: "int256";
|
|
2224
2224
|
readonly type: "int256";
|
|
2225
2225
|
}, {
|
|
2226
|
-
readonly name: "
|
|
2226
|
+
readonly name: "harvestedTheta";
|
|
2227
2227
|
readonly internalType: "int256";
|
|
2228
2228
|
readonly type: "int256";
|
|
2229
2229
|
}, {
|
|
@@ -3116,26 +3116,6 @@ export declare const fPoolManagerAbi: readonly [{
|
|
|
3116
3116
|
readonly indexed: true;
|
|
3117
3117
|
}];
|
|
3118
3118
|
readonly name: "CollectorProposed";
|
|
3119
|
-
}, {
|
|
3120
|
-
readonly type: "event";
|
|
3121
|
-
readonly anonymous: false;
|
|
3122
|
-
readonly inputs: readonly [{
|
|
3123
|
-
readonly name: "poolId";
|
|
3124
|
-
readonly internalType: "bytes32";
|
|
3125
|
-
readonly type: "bytes32";
|
|
3126
|
-
readonly indexed: true;
|
|
3127
|
-
}, {
|
|
3128
|
-
readonly name: "from";
|
|
3129
|
-
readonly internalType: "address";
|
|
3130
|
-
readonly type: "address";
|
|
3131
|
-
readonly indexed: true;
|
|
3132
|
-
}, {
|
|
3133
|
-
readonly name: "amount";
|
|
3134
|
-
readonly internalType: "uint256";
|
|
3135
|
-
readonly type: "uint256";
|
|
3136
|
-
readonly indexed: false;
|
|
3137
|
-
}];
|
|
3138
|
-
readonly name: "Deepen";
|
|
3139
3119
|
}, {
|
|
3140
3120
|
readonly type: "event";
|
|
3141
3121
|
readonly anonymous: false;
|
|
@@ -4103,20 +4083,6 @@ export declare const fPoolSponsorAbi: readonly [{
|
|
|
4103
4083
|
readonly type: "uint8";
|
|
4104
4084
|
}];
|
|
4105
4085
|
readonly stateMutability: "view";
|
|
4106
|
-
}, {
|
|
4107
|
-
readonly type: "function";
|
|
4108
|
-
readonly inputs: readonly [{
|
|
4109
|
-
readonly name: "poolId";
|
|
4110
|
-
readonly internalType: "bytes32";
|
|
4111
|
-
readonly type: "bytes32";
|
|
4112
|
-
}, {
|
|
4113
|
-
readonly name: "amount";
|
|
4114
|
-
readonly internalType: "uint256";
|
|
4115
|
-
readonly type: "uint256";
|
|
4116
|
-
}];
|
|
4117
|
-
readonly name: "deepen";
|
|
4118
|
-
readonly outputs: readonly [];
|
|
4119
|
-
readonly stateMutability: "nonpayable";
|
|
4120
4086
|
}, {
|
|
4121
4087
|
readonly type: "function";
|
|
4122
4088
|
readonly inputs: readonly [{
|
|
@@ -4830,26 +4796,6 @@ export declare const fPoolSponsorAbi: readonly [{
|
|
|
4830
4796
|
readonly indexed: true;
|
|
4831
4797
|
}];
|
|
4832
4798
|
readonly name: "CollectorProposed";
|
|
4833
|
-
}, {
|
|
4834
|
-
readonly type: "event";
|
|
4835
|
-
readonly anonymous: false;
|
|
4836
|
-
readonly inputs: readonly [{
|
|
4837
|
-
readonly name: "poolId";
|
|
4838
|
-
readonly internalType: "bytes32";
|
|
4839
|
-
readonly type: "bytes32";
|
|
4840
|
-
readonly indexed: true;
|
|
4841
|
-
}, {
|
|
4842
|
-
readonly name: "from";
|
|
4843
|
-
readonly internalType: "address";
|
|
4844
|
-
readonly type: "address";
|
|
4845
|
-
readonly indexed: true;
|
|
4846
|
-
}, {
|
|
4847
|
-
readonly name: "amount";
|
|
4848
|
-
readonly internalType: "uint256";
|
|
4849
|
-
readonly type: "uint256";
|
|
4850
|
-
readonly indexed: false;
|
|
4851
|
-
}];
|
|
4852
|
-
readonly name: "Deepen";
|
|
4853
4799
|
}, {
|
|
4854
4800
|
readonly type: "event";
|
|
4855
4801
|
readonly anonymous: false;
|
|
@@ -5859,7 +5805,7 @@ export declare const logswapLensAbi: readonly [{
|
|
|
5859
5805
|
readonly internalType: "int256";
|
|
5860
5806
|
readonly type: "int256";
|
|
5861
5807
|
}, {
|
|
5862
|
-
readonly name: "
|
|
5808
|
+
readonly name: "harvestedTheta";
|
|
5863
5809
|
readonly internalType: "int256";
|
|
5864
5810
|
readonly type: "int256";
|
|
5865
5811
|
}, {
|
package/dist/generated.js
CHANGED
|
@@ -1299,7 +1299,7 @@ export const fPoolManagerAbi = [
|
|
|
1299
1299
|
{ name: 'L', internalType: 'uint256', type: 'uint256' },
|
|
1300
1300
|
{ name: 'shares', internalType: 'uint256', type: 'uint256' },
|
|
1301
1301
|
{ name: 'theta0', internalType: 'int256', type: 'int256' },
|
|
1302
|
-
{ name: '
|
|
1302
|
+
{ name: 'harvestedTheta', internalType: 'int256', type: 'int256' },
|
|
1303
1303
|
{
|
|
1304
1304
|
name: 'pendingAuthority',
|
|
1305
1305
|
internalType: 'address',
|
|
@@ -1845,26 +1845,6 @@ export const fPoolManagerAbi = [
|
|
|
1845
1845
|
],
|
|
1846
1846
|
name: 'CollectorProposed',
|
|
1847
1847
|
},
|
|
1848
|
-
{
|
|
1849
|
-
type: 'event',
|
|
1850
|
-
anonymous: false,
|
|
1851
|
-
inputs: [
|
|
1852
|
-
{
|
|
1853
|
-
name: 'poolId',
|
|
1854
|
-
internalType: 'bytes32',
|
|
1855
|
-
type: 'bytes32',
|
|
1856
|
-
indexed: true,
|
|
1857
|
-
},
|
|
1858
|
-
{ name: 'from', internalType: 'address', type: 'address', indexed: true },
|
|
1859
|
-
{
|
|
1860
|
-
name: 'amount',
|
|
1861
|
-
internalType: 'uint256',
|
|
1862
|
-
type: 'uint256',
|
|
1863
|
-
indexed: false,
|
|
1864
|
-
},
|
|
1865
|
-
],
|
|
1866
|
-
name: 'Deepen',
|
|
1867
|
-
},
|
|
1868
1848
|
{
|
|
1869
1849
|
type: 'event',
|
|
1870
1850
|
anonymous: false,
|
|
@@ -2589,16 +2569,6 @@ export const fPoolSponsorAbi = [
|
|
|
2589
2569
|
outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }],
|
|
2590
2570
|
stateMutability: 'view',
|
|
2591
2571
|
},
|
|
2592
|
-
{
|
|
2593
|
-
type: 'function',
|
|
2594
|
-
inputs: [
|
|
2595
|
-
{ name: 'poolId', internalType: 'bytes32', type: 'bytes32' },
|
|
2596
|
-
{ name: 'amount', internalType: 'uint256', type: 'uint256' },
|
|
2597
|
-
],
|
|
2598
|
-
name: 'deepen',
|
|
2599
|
-
outputs: [],
|
|
2600
|
-
stateMutability: 'nonpayable',
|
|
2601
|
-
},
|
|
2602
2572
|
{
|
|
2603
2573
|
type: 'function',
|
|
2604
2574
|
inputs: [
|
|
@@ -3083,26 +3053,6 @@ export const fPoolSponsorAbi = [
|
|
|
3083
3053
|
],
|
|
3084
3054
|
name: 'CollectorProposed',
|
|
3085
3055
|
},
|
|
3086
|
-
{
|
|
3087
|
-
type: 'event',
|
|
3088
|
-
anonymous: false,
|
|
3089
|
-
inputs: [
|
|
3090
|
-
{
|
|
3091
|
-
name: 'poolId',
|
|
3092
|
-
internalType: 'bytes32',
|
|
3093
|
-
type: 'bytes32',
|
|
3094
|
-
indexed: true,
|
|
3095
|
-
},
|
|
3096
|
-
{ name: 'from', internalType: 'address', type: 'address', indexed: true },
|
|
3097
|
-
{
|
|
3098
|
-
name: 'amount',
|
|
3099
|
-
internalType: 'uint256',
|
|
3100
|
-
type: 'uint256',
|
|
3101
|
-
indexed: false,
|
|
3102
|
-
},
|
|
3103
|
-
],
|
|
3104
|
-
name: 'Deepen',
|
|
3105
|
-
},
|
|
3106
3056
|
{
|
|
3107
3057
|
type: 'event',
|
|
3108
3058
|
anonymous: false,
|
|
@@ -3823,7 +3773,7 @@ export const logswapLensAbi = [
|
|
|
3823
3773
|
{ name: 'L', internalType: 'uint256', type: 'uint256' },
|
|
3824
3774
|
{ name: 'shares', internalType: 'uint256', type: 'uint256' },
|
|
3825
3775
|
{ name: 'theta0', internalType: 'int256', type: 'int256' },
|
|
3826
|
-
{ name: '
|
|
3776
|
+
{ name: 'harvestedTheta', internalType: 'int256', type: 'int256' },
|
|
3827
3777
|
{
|
|
3828
3778
|
name: 'pendingAuthority',
|
|
3829
3779
|
internalType: 'address',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@logswap/sdk",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.40",
|
|
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",
|
package/src/fpool.ts
CHANGED
|
@@ -128,7 +128,7 @@ export async function getFPool(c: LogswapClient, poolId: Hex): Promise<FPoolStat
|
|
|
128
128
|
shares: bigint;
|
|
129
129
|
theta0: bigint;
|
|
130
130
|
bigSigma: bigint;
|
|
131
|
-
|
|
131
|
+
harvestedTheta: bigint;
|
|
132
132
|
pendingAuthority: Address;
|
|
133
133
|
operator: Address;
|
|
134
134
|
minBuffer: bigint;
|
|
@@ -467,11 +467,6 @@ export async function fPoolDividendOf(c: LogswapClient, poolId: Hex, holder: Add
|
|
|
467
467
|
/** The lever's floor: `harvest` may not take Q/L under ln 1.25 — the floor stays ≥ 20% below the mark (decisions 025). */
|
|
468
468
|
export const LEVER_FLOOR = 223143551314209755n;
|
|
469
469
|
|
|
470
|
-
/** 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. */
|
|
471
|
-
export async function fPoolDeepen(c: LogswapClient, a: { poolId: Hex; amount: bigint; account: Address }) {
|
|
472
|
-
return writeFPool(c, a.poolId, "deepen", [a.amount], a.account);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
470
|
// ─── internals ────────────────────────────────────────────────────────────────
|
|
476
471
|
|
|
477
472
|
function defaultDeadline(): bigint {
|
|
@@ -920,6 +915,108 @@ export async function fPoolRelaunch(
|
|
|
920
915
|
return writeFPool0(c, "multicall", [calls], a.account);
|
|
921
916
|
}
|
|
922
917
|
|
|
918
|
+
/** ERC-6909 shares sent here are locked for good — the seed's custody (custody.md §4(b)). */
|
|
919
|
+
export const DEAD_ADDRESS: Address = "0x000000000000000000000000000000000000dEaD";
|
|
920
|
+
/** The manager's `MIN_SHARES`: the seed mints this much to 0xdead itself, the rest to the seeder. */
|
|
921
|
+
export const F_MIN_SHARES = 1000n;
|
|
922
|
+
|
|
923
|
+
export interface FPoolLaunchArgs extends Omit<FPoolCreateArgs, "account"> {
|
|
924
|
+
L0: bigint;
|
|
925
|
+
/** Quote the seed pulls. A pad seeds at 0 — pure float, a resting ask, nothing raised. */
|
|
926
|
+
Q0: bigint;
|
|
927
|
+
/**
|
|
928
|
+
* Send every share the seed mints to the creator (`L0 − MIN_SHARES`) to 0xdead in the same
|
|
929
|
+
* batch: the float and the raise can never be burned out from under the buyers. The lever
|
|
930
|
+
* (harvest) is the authority's and survives it; the exit does not. A pad's default posture.
|
|
931
|
+
*/
|
|
932
|
+
lockSeed?: boolean;
|
|
933
|
+
/**
|
|
934
|
+
* An opening buy of leg `j` (an index into `bases` AS GIVEN) for `amountIn` of quote, ON THE
|
|
935
|
+
* MANAGER — the same sender, a plain allowance to the manager, the router nowhere near it. A
|
|
936
|
+
* pad seeds at Q = 0, so until someone trades it the mark sits at p₀; buying inside the launch
|
|
937
|
+
* gives it a price that has moved and a buffer under it. Nothing can trade between the seed and
|
|
938
|
+
* this buy — they are one transaction — so `minOut` is safe at its default of 0.
|
|
939
|
+
*/
|
|
940
|
+
openBuy?: { j: number; amountIn: bigint; minOut?: bigint };
|
|
941
|
+
/** The pool's label, set in the batch (≤ 31 bytes of UTF-8). */
|
|
942
|
+
name?: string;
|
|
943
|
+
/** Gate minting, list the creator, appoint them operator (decisions 021) — three calls, in the batch. */
|
|
944
|
+
privatePool?: boolean;
|
|
945
|
+
/**
|
|
946
|
+
* The pool already exists (a previous launch got as far as `initialize` and no further — a seed
|
|
947
|
+
* that reverted, a closed tab, before the launch was one transaction), so `initialize` is left
|
|
948
|
+
* out: the key is a pure function of the arguments and a second `initialize` can only revert.
|
|
949
|
+
*/
|
|
950
|
+
initialized?: boolean;
|
|
951
|
+
/** Anything else, pre-encoded against {@link fPoolManagerAbi}, appended after the above. */
|
|
952
|
+
extra?: Hex[];
|
|
953
|
+
account: Address;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* The launch's calls, in order — the batch {@link fPoolLaunch} sends. Pure, so a form can show
|
|
958
|
+
* what it is about to send, and a test can decode it. Legs are sorted here with their weights and
|
|
959
|
+
* reserves (the key's canonical order; `openBuy.j` is re-indexed to match), and the weights are
|
|
960
|
+
* checked here, where the message is readable.
|
|
961
|
+
*/
|
|
962
|
+
export function fPoolLaunchCalls(
|
|
963
|
+
poolId: Hex,
|
|
964
|
+
a: FPoolLaunchArgs & ({ r0: bigint[] } | { x0: bigint[] }),
|
|
965
|
+
): Hex[] {
|
|
966
|
+
const sum = a.weights.reduce((x, y) => x + y, 0n);
|
|
967
|
+
if (sum !== WAD) throw new Error(`logswap: weights sum to ${sum}, expected 1e18`);
|
|
968
|
+
const given = "r0" in a ? a.r0 : a.x0.map((x, j) => fPoolReserveAt((a.weights[j]! * a.L0) / WAD, x));
|
|
969
|
+
if (given.length !== a.bases.length) throw new Error(`logswap: ${given.length} reserves for ${a.bases.length} legs`);
|
|
970
|
+
const { bases, companions } = sortFPoolLegs(a.bases, a.weights, given);
|
|
971
|
+
const key = { quote: a.quote, bases, weights: companions[0]!, phi: a.phi, lockStrike: a.lockStrike, authority: a.authority, salt: a.salt ?? ZERO_SALT };
|
|
972
|
+
const enc = (functionName: string, args: unknown[]) =>
|
|
973
|
+
encodeFunctionData({ abi: fPoolManagerAbi, functionName, args } as never) as Hex;
|
|
974
|
+
const calls: Hex[] = [];
|
|
975
|
+
if (!a.initialized) calls.push(enc("initialize", [key]));
|
|
976
|
+
calls.push(enc("seed", [poolId, a.L0, companions[1]!, a.Q0]));
|
|
977
|
+
// gen 0 by construction: a launch is the pool's FIRST seed — a relaunch is `fPoolRelaunch`
|
|
978
|
+
if (a.lockSeed) calls.push(enc("transfer", [DEAD_ADDRESS, fPoolShareId(poolId, 0), a.L0 - F_MIN_SHARES]));
|
|
979
|
+
if (a.openBuy) {
|
|
980
|
+
const j = bases.indexOf(a.bases[a.openBuy.j]!);
|
|
981
|
+
if (j < 0) throw new Error(`logswap: openBuy.j = ${a.openBuy.j} is not a leg`);
|
|
982
|
+
calls.push(enc("swapQuoteIn", [poolId, BigInt(j), a.openBuy.amountIn, a.openBuy.minOut ?? 0n, a.account]));
|
|
983
|
+
}
|
|
984
|
+
if (a.name) calls.push(enc("setName", [poolId, textToBytes32(a.name)]));
|
|
985
|
+
if (a.privatePool) {
|
|
986
|
+
calls.push(enc("setGates", [poolId, true, false]));
|
|
987
|
+
calls.push(enc("setAllowed", [poolId, [a.account], true]));
|
|
988
|
+
calls.push(enc("appointOperator", [poolId, a.account]));
|
|
989
|
+
}
|
|
990
|
+
calls.push(...(a.extra ?? []));
|
|
991
|
+
return calls;
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
/**
|
|
995
|
+
* Create a pool as ONE transaction: `initialize`, `seed`, the seed lock, the opening buy, the
|
|
996
|
+
* name, the private-pool gates — the manager's `multicall`, the creator as sender throughout.
|
|
997
|
+
* Either every call lands or none does; there is no half-built pool to resume.
|
|
998
|
+
*
|
|
999
|
+
* Why the manager and not the router: every one of these entries authenticates by `msg.sender`
|
|
1000
|
+
* (`seed` is authority-only, so is everything after it). Routed, the router would be the sender
|
|
1001
|
+
* — the authority, the holder of the seed shares — and the handover back is two-step, so it
|
|
1002
|
+
* could not even close in the same transaction. `multicall` is delegatecall-to-self, so the
|
|
1003
|
+
* sender survives, which is what the manager's own doc says a router cannot do.
|
|
1004
|
+
*
|
|
1005
|
+
* What the batch PULLS, by plain allowance to the manager (never Permit2): `r0[j]` of each base,
|
|
1006
|
+
* `Q0` of quote, plus `openBuy.amountIn` of quote. Grant those first — one `approve` per token,
|
|
1007
|
+
* once ever ({@link approveTokenForFPoolManager}, {@link fPoolManagerAllowanceOk}).
|
|
1008
|
+
*
|
|
1009
|
+
* Returns the hash and the pool's id (the key's hash, {@link fPoolIdOf}).
|
|
1010
|
+
*/
|
|
1011
|
+
export async function fPoolLaunch(
|
|
1012
|
+
c: LogswapClient,
|
|
1013
|
+
a: FPoolLaunchArgs & ({ r0: bigint[] } | { x0: bigint[] }),
|
|
1014
|
+
): Promise<{ hash: Hash; poolId: Hex }> {
|
|
1015
|
+
const poolId = await fPoolIdOf(c, a);
|
|
1016
|
+
const hash = await writeFPool0(c, "multicall", [fPoolLaunchCalls(poolId, a)], a.account);
|
|
1017
|
+
return { hash, poolId };
|
|
1018
|
+
}
|
|
1019
|
+
|
|
923
1020
|
/**
|
|
924
1021
|
* Propose the next authority — step one of two (contracts `2aa6b7b`, decisions 020). Nothing moves
|
|
925
1022
|
* until `next` accepts; proposing again (the zero address included) cancels a pending proposal.
|
|
@@ -1161,7 +1258,7 @@ export async function fPoolShareHolders(
|
|
|
1161
1258
|
.sort((a, b) => (b.shares > a.shares ? 1 : -1));
|
|
1162
1259
|
}
|
|
1163
1260
|
|
|
1164
|
-
/** 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,
|
|
1261
|
+
/** 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, harvestedTheta). */
|
|
1165
1262
|
export async function getFPoolsRaw(c: LogswapClient, poolIds: Hex[]): Promise<readonly unknown[]> {
|
|
1166
1263
|
const { logswapLensAbi } = await import("./generated.js");
|
|
1167
1264
|
return (await c.public.readContract({ address: c.addresses.lens, abi: logswapLensAbi, functionName: "getFPools", args: [poolIds] } as never)) as readonly unknown[];
|
package/src/generated.ts
CHANGED
|
@@ -1302,7 +1302,7 @@ export const fPoolManagerAbi = [
|
|
|
1302
1302
|
{ name: 'L', internalType: 'uint256', type: 'uint256' },
|
|
1303
1303
|
{ name: 'shares', internalType: 'uint256', type: 'uint256' },
|
|
1304
1304
|
{ name: 'theta0', internalType: 'int256', type: 'int256' },
|
|
1305
|
-
{ name: '
|
|
1305
|
+
{ name: 'harvestedTheta', internalType: 'int256', type: 'int256' },
|
|
1306
1306
|
{
|
|
1307
1307
|
name: 'pendingAuthority',
|
|
1308
1308
|
internalType: 'address',
|
|
@@ -1848,26 +1848,6 @@ export const fPoolManagerAbi = [
|
|
|
1848
1848
|
],
|
|
1849
1849
|
name: 'CollectorProposed',
|
|
1850
1850
|
},
|
|
1851
|
-
{
|
|
1852
|
-
type: 'event',
|
|
1853
|
-
anonymous: false,
|
|
1854
|
-
inputs: [
|
|
1855
|
-
{
|
|
1856
|
-
name: 'poolId',
|
|
1857
|
-
internalType: 'bytes32',
|
|
1858
|
-
type: 'bytes32',
|
|
1859
|
-
indexed: true,
|
|
1860
|
-
},
|
|
1861
|
-
{ name: 'from', internalType: 'address', type: 'address', indexed: true },
|
|
1862
|
-
{
|
|
1863
|
-
name: 'amount',
|
|
1864
|
-
internalType: 'uint256',
|
|
1865
|
-
type: 'uint256',
|
|
1866
|
-
indexed: false,
|
|
1867
|
-
},
|
|
1868
|
-
],
|
|
1869
|
-
name: 'Deepen',
|
|
1870
|
-
},
|
|
1871
1851
|
{
|
|
1872
1852
|
type: 'event',
|
|
1873
1853
|
anonymous: false,
|
|
@@ -2594,16 +2574,6 @@ export const fPoolSponsorAbi = [
|
|
|
2594
2574
|
outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }],
|
|
2595
2575
|
stateMutability: 'view',
|
|
2596
2576
|
},
|
|
2597
|
-
{
|
|
2598
|
-
type: 'function',
|
|
2599
|
-
inputs: [
|
|
2600
|
-
{ name: 'poolId', internalType: 'bytes32', type: 'bytes32' },
|
|
2601
|
-
{ name: 'amount', internalType: 'uint256', type: 'uint256' },
|
|
2602
|
-
],
|
|
2603
|
-
name: 'deepen',
|
|
2604
|
-
outputs: [],
|
|
2605
|
-
stateMutability: 'nonpayable',
|
|
2606
|
-
},
|
|
2607
2577
|
{
|
|
2608
2578
|
type: 'function',
|
|
2609
2579
|
inputs: [
|
|
@@ -3088,26 +3058,6 @@ export const fPoolSponsorAbi = [
|
|
|
3088
3058
|
],
|
|
3089
3059
|
name: 'CollectorProposed',
|
|
3090
3060
|
},
|
|
3091
|
-
{
|
|
3092
|
-
type: 'event',
|
|
3093
|
-
anonymous: false,
|
|
3094
|
-
inputs: [
|
|
3095
|
-
{
|
|
3096
|
-
name: 'poolId',
|
|
3097
|
-
internalType: 'bytes32',
|
|
3098
|
-
type: 'bytes32',
|
|
3099
|
-
indexed: true,
|
|
3100
|
-
},
|
|
3101
|
-
{ name: 'from', internalType: 'address', type: 'address', indexed: true },
|
|
3102
|
-
{
|
|
3103
|
-
name: 'amount',
|
|
3104
|
-
internalType: 'uint256',
|
|
3105
|
-
type: 'uint256',
|
|
3106
|
-
indexed: false,
|
|
3107
|
-
},
|
|
3108
|
-
],
|
|
3109
|
-
name: 'Deepen',
|
|
3110
|
-
},
|
|
3111
3061
|
{
|
|
3112
3062
|
type: 'event',
|
|
3113
3063
|
anonymous: false,
|
|
@@ -3830,7 +3780,7 @@ export const logswapLensAbi = [
|
|
|
3830
3780
|
{ name: 'L', internalType: 'uint256', type: 'uint256' },
|
|
3831
3781
|
{ name: 'shares', internalType: 'uint256', type: 'uint256' },
|
|
3832
3782
|
{ name: 'theta0', internalType: 'int256', type: 'int256' },
|
|
3833
|
-
{ name: '
|
|
3783
|
+
{ name: 'harvestedTheta', internalType: 'int256', type: 'int256' },
|
|
3834
3784
|
{
|
|
3835
3785
|
name: 'pendingAuthority',
|
|
3836
3786
|
internalType: 'address',
|