@interest-protocol/blast-migrators-sdk 0.0.0-stage → 0.1.0
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 +8 -2
- package/dist/bluefin-pool.d.ts +57 -0
- package/dist/bluefin-pool.d.ts.map +1 -0
- package/dist/bluefin-pool.js +102 -0
- package/dist/bluefin-pool.js.map +1 -0
- package/dist/cetus-pool.d.ts +44 -0
- package/dist/cetus-pool.d.ts.map +1 -0
- package/dist/cetus-pool.js +57 -0
- package/dist/cetus-pool.js.map +1 -0
- package/dist/client.d.ts +25 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +34 -0
- package/dist/client.js.map +1 -0
- package/dist/events.d.ts +168 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +180 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/reducer.d.ts +139 -0
- package/dist/reducer.d.ts.map +1 -0
- package/dist/reducer.js +376 -0
- package/dist/reducer.js.map +1 -0
- package/dist/state.d.ts +166 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +187 -0
- package/dist/state.js.map +1 -0
- package/dist/transactions.d.ts +314 -0
- package/dist/transactions.d.ts.map +1 -0
- package/dist/transactions.js +604 -0
- package/dist/transactions.js.map +1 -0
- package/package.json +68 -4
- package/src/bluefin-pool.ts +180 -0
- package/src/cetus-pool.ts +107 -0
- package/src/client.ts +76 -0
- package/src/events.ts +285 -0
- package/src/index.ts +8 -0
- package/src/reducer.ts +562 -0
- package/src/state.ts +316 -0
- package/src/transactions.ts +1068 -0
|
@@ -0,0 +1,1068 @@
|
|
|
1
|
+
import type { CoinSourceOptions } from "@interest-protocol/blast-core/coins";
|
|
2
|
+
import { grossGasBudget } from "@interest-protocol/blast-core/gas";
|
|
3
|
+
import {
|
|
4
|
+
requirePositiveU64,
|
|
5
|
+
requireU64,
|
|
6
|
+
} from "@interest-protocol/blast-core/integers";
|
|
7
|
+
import {
|
|
8
|
+
deploymentObject,
|
|
9
|
+
moveResults,
|
|
10
|
+
} from "@interest-protocol/blast-core/ptb";
|
|
11
|
+
import type {
|
|
12
|
+
RewardManifest,
|
|
13
|
+
RewardProof,
|
|
14
|
+
} from "@interest-protocol/blast-core/rewards/allocations";
|
|
15
|
+
import {
|
|
16
|
+
MIGRATOR_REWARD_LEAF_DOMAIN,
|
|
17
|
+
rewardAddress,
|
|
18
|
+
rewardDigest,
|
|
19
|
+
validateRewardManifest,
|
|
20
|
+
} from "@interest-protocol/blast-core/rewards/allocations";
|
|
21
|
+
import type {
|
|
22
|
+
SharedObjectIdentity,
|
|
23
|
+
SharedObjectReference,
|
|
24
|
+
} from "@interest-protocol/blast-core/sui";
|
|
25
|
+
import {
|
|
26
|
+
normalizeSharedObjectIdentity,
|
|
27
|
+
normalizeSharedObjectReference,
|
|
28
|
+
normalizeSuiPackageReference,
|
|
29
|
+
} from "@interest-protocol/blast-core/sui";
|
|
30
|
+
import type { FeeSplit } from "@interest-protocol/blast-launchpad-sdk/allocation";
|
|
31
|
+
import type {
|
|
32
|
+
BlastFunAdminRole,
|
|
33
|
+
LaunchpadDeployment,
|
|
34
|
+
LaunchSettings,
|
|
35
|
+
LaunchTypes,
|
|
36
|
+
PreShareBuyInput,
|
|
37
|
+
} from "@interest-protocol/blast-launchpad-sdk/transactions";
|
|
38
|
+
import {
|
|
39
|
+
addLaunchCompletion,
|
|
40
|
+
LaunchpadCalls,
|
|
41
|
+
normalizeLaunchTypes,
|
|
42
|
+
} from "@interest-protocol/blast-launchpad-sdk/transactions";
|
|
43
|
+
import type {
|
|
44
|
+
TransactionArgument,
|
|
45
|
+
TransactionObjectArgument,
|
|
46
|
+
TransactionObjectInput,
|
|
47
|
+
TransactionResult,
|
|
48
|
+
} from "@mysten/sui/transactions";
|
|
49
|
+
import { Transaction } from "@mysten/sui/transactions";
|
|
50
|
+
import { normalizeStructTag, normalizeSuiAddress } from "@mysten/sui/utils";
|
|
51
|
+
import type { MigratorVenue } from "./state.ts";
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The vault's partner, when `LpVaultState.partnerId` is set: the collection
|
|
55
|
+
* then pays it and Blast the LP fees the vault held.
|
|
56
|
+
*/
|
|
57
|
+
export type LpFeePartner = {
|
|
58
|
+
partner?: SharedObjectReference<false> | null;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export type MigratorsDeployment = {
|
|
62
|
+
packageId: string;
|
|
63
|
+
originalPackageId: string;
|
|
64
|
+
launchpad: LaunchpadDeployment;
|
|
65
|
+
/** Migrators `blast_fun_migrators::PackageVersion` checked by every protected entry. */
|
|
66
|
+
migratorsVersion: SharedObjectIdentity;
|
|
67
|
+
/** Migrators `lp_fee_policy::LpFeePolicy` read by every LP-fee collection. */
|
|
68
|
+
lpFeePolicy: SharedObjectIdentity;
|
|
69
|
+
/** Migrators `venue_config::VenueConfig`, holding each Meme's Cetus `PoolCreationCap`. */
|
|
70
|
+
venueConfig: SharedObjectIdentity;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
import type { CetusMemeSide } from "@interest-protocol/blast-core/cetus";
|
|
74
|
+
|
|
75
|
+
export type { CetusMemeSide } from "@interest-protocol/blast-core/cetus";
|
|
76
|
+
|
|
77
|
+
/** The Cetus CLMM `config::GlobalConfig` every Cetus route reads. */
|
|
78
|
+
export type CetusObjects = {
|
|
79
|
+
/** Cetus CLMM `config::GlobalConfig`. */
|
|
80
|
+
cetusConfig: SharedObjectReference<false>;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/** Settings for starting a launch through an adapter in one transaction. */
|
|
84
|
+
export type CreateLaunchOptions = LaunchTypes &
|
|
85
|
+
LaunchSettings &
|
|
86
|
+
CoinSourceOptions & {
|
|
87
|
+
/** The `LaunchTicket<Meme>` the generated package's initializer transferred to its publisher. */
|
|
88
|
+
ticket: TransactionObjectInput;
|
|
89
|
+
/** The Meme `Currency<Meme>` in the Coin Registry, fixed at finalization. */
|
|
90
|
+
memeCurrency: SharedObjectReference<true>;
|
|
91
|
+
/** `LaunchConfig.creation_fee` in MIST, paid as an exact SUI coin. */
|
|
92
|
+
creationFee: bigint;
|
|
93
|
+
preShareBuy?: PreShareBuyInput;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/** Maximum Merkle proof depth the holder-reward leaf count (65,536) allows. */
|
|
97
|
+
export const MAX_HOLDER_REWARD_PROOF_DEPTH = 16;
|
|
98
|
+
|
|
99
|
+
export class MigratorCalls {
|
|
100
|
+
readonly deployment: MigratorsDeployment;
|
|
101
|
+
readonly launchpad: LaunchpadCalls;
|
|
102
|
+
|
|
103
|
+
constructor(deployment: MigratorsDeployment) {
|
|
104
|
+
this.launchpad = new LaunchpadCalls(deployment.launchpad);
|
|
105
|
+
this.deployment = {
|
|
106
|
+
...normalizeSuiPackageReference("migrators", deployment),
|
|
107
|
+
launchpad: this.launchpad.deployment,
|
|
108
|
+
migratorsVersion: normalizeSharedObjectIdentity(
|
|
109
|
+
"migratorsVersion",
|
|
110
|
+
deployment.migratorsVersion,
|
|
111
|
+
),
|
|
112
|
+
lpFeePolicy: normalizeSharedObjectIdentity(
|
|
113
|
+
"lpFeePolicy",
|
|
114
|
+
deployment.lpFeePolicy,
|
|
115
|
+
),
|
|
116
|
+
venueConfig: normalizeSharedObjectIdentity(
|
|
117
|
+
"venueConfig",
|
|
118
|
+
deployment.venueConfig,
|
|
119
|
+
),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** The adapter witness type a launch stores as its `migration_witness`. */
|
|
124
|
+
migrationWitnessType(venue: MigratorVenue): string {
|
|
125
|
+
return normalizeStructTag(
|
|
126
|
+
`${this.deployment.originalPackageId}::${venue}::Witness`,
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
signIn(options: {
|
|
131
|
+
adminCap: TransactionObjectInput;
|
|
132
|
+
role: BlastFunAdminRole;
|
|
133
|
+
}) {
|
|
134
|
+
return this.launchpad.signIn(options);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Starts a Cetus launch at `tickSpacing`: Cetus derives the fee rate, and the
|
|
139
|
+
* Meme type's single `PoolCreationCap` is minted and reserved for the pair.
|
|
140
|
+
* Returns the `LaunchInitializer`, which the same PTB must finalize.
|
|
141
|
+
*/
|
|
142
|
+
newCetusLaunch(
|
|
143
|
+
options: LaunchTypes &
|
|
144
|
+
CetusObjects & {
|
|
145
|
+
ticket: TransactionObjectInput;
|
|
146
|
+
cetusPools: SharedObjectReference<true>;
|
|
147
|
+
tickSpacing: number;
|
|
148
|
+
},
|
|
149
|
+
) {
|
|
150
|
+
const types = normalizeLaunchTypes(options);
|
|
151
|
+
const tickSpacing = requireU32("tickSpacing", options.tickSpacing);
|
|
152
|
+
return (tx: Transaction): TransactionResult =>
|
|
153
|
+
tx.moveCall({
|
|
154
|
+
target: `${this.deployment.packageId}::cetus::new`,
|
|
155
|
+
typeArguments: [types.memeType, types.quoteType],
|
|
156
|
+
arguments: [
|
|
157
|
+
tx.object(options.ticket),
|
|
158
|
+
this.#migratorsVersion(tx),
|
|
159
|
+
this.#launchpadVersion(tx),
|
|
160
|
+
this.#launchConfig(tx),
|
|
161
|
+
deploymentObject(tx, this.deployment.venueConfig, true),
|
|
162
|
+
sharedObject(tx, "cetusConfig", options.cetusConfig, false),
|
|
163
|
+
sharedObject(tx, "cetusPools", options.cetusPools, true),
|
|
164
|
+
tx.pure.u32(tickSpacing),
|
|
165
|
+
],
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Starts a Bluefin launch at the creator's tier (tick spacing 1-400, fee rate
|
|
171
|
+
* 1-20,000, Bluefin's own bounds). Returns the `LaunchInitializer`.
|
|
172
|
+
*/
|
|
173
|
+
newBluefinLaunch(
|
|
174
|
+
options: LaunchTypes & {
|
|
175
|
+
ticket: TransactionObjectInput;
|
|
176
|
+
tickSpacing: number;
|
|
177
|
+
feeRate: bigint;
|
|
178
|
+
},
|
|
179
|
+
) {
|
|
180
|
+
const types = normalizeLaunchTypes(options);
|
|
181
|
+
const tickSpacing = requireU32("tickSpacing", options.tickSpacing);
|
|
182
|
+
requireU64("feeRate", options.feeRate);
|
|
183
|
+
return (tx: Transaction): TransactionResult =>
|
|
184
|
+
tx.moveCall({
|
|
185
|
+
target: `${this.deployment.packageId}::bluefin::new`,
|
|
186
|
+
typeArguments: [types.memeType, types.quoteType],
|
|
187
|
+
arguments: [
|
|
188
|
+
tx.object(options.ticket),
|
|
189
|
+
this.#migratorsVersion(tx),
|
|
190
|
+
this.#launchpadVersion(tx),
|
|
191
|
+
this.#launchConfig(tx),
|
|
192
|
+
tx.pure.u32(tickSpacing),
|
|
193
|
+
tx.pure.u64(options.feeRate),
|
|
194
|
+
],
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Migrates a MigrationReady Cetus launch: creates the pool with the reserved
|
|
200
|
+
* capability, seeds full-range liquidity, and burns the position through
|
|
201
|
+
* Cetus LP Burn. Anyone may call it.
|
|
202
|
+
*/
|
|
203
|
+
migrateCetus(
|
|
204
|
+
options: LaunchTypes &
|
|
205
|
+
CetusObjects & {
|
|
206
|
+
memeSide: CetusMemeSide;
|
|
207
|
+
launch: SharedObjectReference<true>;
|
|
208
|
+
memeCurrency: SharedObjectReference<true>;
|
|
209
|
+
cetusPools: SharedObjectReference<true>;
|
|
210
|
+
/** Cetus LP Burn `lp_burn::BurnManager`. */
|
|
211
|
+
burnManager: SharedObjectReference<true>;
|
|
212
|
+
},
|
|
213
|
+
) {
|
|
214
|
+
const types = normalizeLaunchTypes(options);
|
|
215
|
+
const memeSide = normalizeMemeSide(options.memeSide);
|
|
216
|
+
return (tx: Transaction): void => {
|
|
217
|
+
// Cetus seeds a new pool's tick skip list from the clock, so its storage
|
|
218
|
+
// differs between simulation and execution by up to 18 bytes, more than
|
|
219
|
+
// the default budget's headroom: budget this transaction at gross cost.
|
|
220
|
+
tx.addBuildPlugin(grossGasBudget());
|
|
221
|
+
tx.moveCall({
|
|
222
|
+
target: `${this.deployment.packageId}::cetus::migrate`,
|
|
223
|
+
typeArguments: cetusTypeArguments(types, memeSide),
|
|
224
|
+
arguments: [
|
|
225
|
+
sharedObject(tx, "launch", options.launch, true),
|
|
226
|
+
this.#migratorsVersion(tx),
|
|
227
|
+
this.#launchpadVersion(tx),
|
|
228
|
+
sharedObject(tx, "memeCurrency", options.memeCurrency, true),
|
|
229
|
+
deploymentObject(tx, this.deployment.venueConfig, false),
|
|
230
|
+
sharedObject(tx, "cetusConfig", options.cetusConfig, false),
|
|
231
|
+
sharedObject(tx, "cetusPools", options.cetusPools, true),
|
|
232
|
+
sharedObject(tx, "burnManager", options.burnManager, true),
|
|
233
|
+
tx.object.clock(),
|
|
234
|
+
],
|
|
235
|
+
});
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Migrates a MigrationReady Bluefin launch into a new `Pool<Meme, Quote>`.
|
|
241
|
+
* `creationFee` must be exactly Bluefin's configured SUI pool-creation fee.
|
|
242
|
+
*/
|
|
243
|
+
migrateBluefin(
|
|
244
|
+
options: LaunchTypes & {
|
|
245
|
+
launch: SharedObjectReference<true>;
|
|
246
|
+
memeCurrency: SharedObjectReference<true>;
|
|
247
|
+
quoteCurrency: SharedObjectReference<false>;
|
|
248
|
+
bluefinConfig: SharedObjectReference<true>;
|
|
249
|
+
creationFee: TransactionObjectInput;
|
|
250
|
+
},
|
|
251
|
+
) {
|
|
252
|
+
const types = normalizeLaunchTypes(options);
|
|
253
|
+
return (tx: Transaction): void => {
|
|
254
|
+
tx.moveCall({
|
|
255
|
+
target: `${this.deployment.packageId}::bluefin::migrate`,
|
|
256
|
+
typeArguments: [types.memeType, types.quoteType],
|
|
257
|
+
arguments: [
|
|
258
|
+
sharedObject(tx, "launch", options.launch, true),
|
|
259
|
+
this.#migratorsVersion(tx),
|
|
260
|
+
this.#launchpadVersion(tx),
|
|
261
|
+
sharedObject(tx, "memeCurrency", options.memeCurrency, true),
|
|
262
|
+
sharedObject(tx, "quoteCurrency", options.quoteCurrency, false),
|
|
263
|
+
sharedObject(tx, "bluefinConfig", options.bluefinConfig, true),
|
|
264
|
+
tx.object(options.creationFee),
|
|
265
|
+
tx.object.clock(),
|
|
266
|
+
],
|
|
267
|
+
});
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Collects the burned migration position's and the auto-LP position's fees,
|
|
273
|
+
* pays Blast's live share, splits the rest, burns the burn share's Meme, and
|
|
274
|
+
* adds the auto-LP share back. Anyone may call it.
|
|
275
|
+
*/
|
|
276
|
+
collectCetusFees(
|
|
277
|
+
options: LaunchTypes &
|
|
278
|
+
CetusObjects & {
|
|
279
|
+
memeSide: CetusMemeSide;
|
|
280
|
+
vault: SharedObjectReference<true>;
|
|
281
|
+
memeCurrency: SharedObjectReference<true>;
|
|
282
|
+
burnManager: SharedObjectReference<false>;
|
|
283
|
+
pool: SharedObjectReference<true>;
|
|
284
|
+
},
|
|
285
|
+
) {
|
|
286
|
+
const types = normalizeLaunchTypes(options);
|
|
287
|
+
const memeSide = normalizeMemeSide(options.memeSide);
|
|
288
|
+
return (tx: Transaction): void => {
|
|
289
|
+
tx.moveCall({
|
|
290
|
+
target: `${this.deployment.packageId}::cetus::collect_fees`,
|
|
291
|
+
typeArguments: cetusTypeArguments(types, memeSide),
|
|
292
|
+
arguments: [
|
|
293
|
+
sharedObject(tx, "vault", options.vault, true),
|
|
294
|
+
this.#migratorsVersion(tx),
|
|
295
|
+
this.#lpFeePolicy(tx),
|
|
296
|
+
sharedObject(tx, "memeCurrency", options.memeCurrency, true),
|
|
297
|
+
sharedObject(tx, "cetusConfig", options.cetusConfig, false),
|
|
298
|
+
sharedObject(tx, "burnManager", options.burnManager, false),
|
|
299
|
+
sharedObject(tx, "pool", options.pool, true),
|
|
300
|
+
tx.object.clock(),
|
|
301
|
+
],
|
|
302
|
+
});
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/** Collects, splits, burns, and adds auto-LP for a Bluefin vault. Anyone may call it. */
|
|
307
|
+
collectBluefinFees(
|
|
308
|
+
options: LaunchTypes & {
|
|
309
|
+
vault: SharedObjectReference<true>;
|
|
310
|
+
memeCurrency: SharedObjectReference<true>;
|
|
311
|
+
bluefinConfig: SharedObjectReference<false>;
|
|
312
|
+
pool: SharedObjectReference<true>;
|
|
313
|
+
},
|
|
314
|
+
) {
|
|
315
|
+
const types = normalizeLaunchTypes(options);
|
|
316
|
+
return (tx: Transaction): void => {
|
|
317
|
+
tx.moveCall({
|
|
318
|
+
target: `${this.deployment.packageId}::bluefin::collect_fees`,
|
|
319
|
+
typeArguments: [types.memeType, types.quoteType],
|
|
320
|
+
arguments: [
|
|
321
|
+
sharedObject(tx, "vault", options.vault, true),
|
|
322
|
+
this.#migratorsVersion(tx),
|
|
323
|
+
this.#lpFeePolicy(tx),
|
|
324
|
+
sharedObject(tx, "memeCurrency", options.memeCurrency, true),
|
|
325
|
+
sharedObject(tx, "bluefinConfig", options.bluefinConfig, false),
|
|
326
|
+
sharedObject(tx, "pool", options.pool, true),
|
|
327
|
+
tx.object.clock(),
|
|
328
|
+
],
|
|
329
|
+
});
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Settles the fees accrued under the current split, then commits `feeSplit`
|
|
335
|
+
* as the vault's split. Only the launch's live `CurveFeeCap` authorizes it.
|
|
336
|
+
* `launch` is read immutably by Move.
|
|
337
|
+
*/
|
|
338
|
+
settleAndUpdateCetusFeeSplit(
|
|
339
|
+
options: LaunchTypes &
|
|
340
|
+
CetusObjects & {
|
|
341
|
+
memeSide: CetusMemeSide;
|
|
342
|
+
vault: SharedObjectReference<true>;
|
|
343
|
+
launch: SharedObjectReference;
|
|
344
|
+
curveFeeCap: TransactionObjectInput;
|
|
345
|
+
memeCurrency: SharedObjectReference<true>;
|
|
346
|
+
burnManager: SharedObjectReference<false>;
|
|
347
|
+
pool: SharedObjectReference<true>;
|
|
348
|
+
feeSplit: FeeSplit;
|
|
349
|
+
},
|
|
350
|
+
) {
|
|
351
|
+
const types = normalizeLaunchTypes(options);
|
|
352
|
+
const memeSide = normalizeMemeSide(options.memeSide);
|
|
353
|
+
const feeSplit = this.launchpad.feeSplit(options.feeSplit);
|
|
354
|
+
return (tx: Transaction): void => {
|
|
355
|
+
tx.moveCall({
|
|
356
|
+
target: `${this.deployment.packageId}::cetus::settle_and_update_fee_split`,
|
|
357
|
+
typeArguments: cetusTypeArguments(types, memeSide),
|
|
358
|
+
arguments: [
|
|
359
|
+
sharedObject(tx, "vault", options.vault, true),
|
|
360
|
+
this.#migratorsVersion(tx),
|
|
361
|
+
this.#lpFeePolicy(tx),
|
|
362
|
+
sharedObject(tx, "launch", options.launch, options.launch.mutable),
|
|
363
|
+
tx.object(options.curveFeeCap),
|
|
364
|
+
sharedObject(tx, "memeCurrency", options.memeCurrency, true),
|
|
365
|
+
sharedObject(tx, "cetusConfig", options.cetusConfig, false),
|
|
366
|
+
sharedObject(tx, "burnManager", options.burnManager, false),
|
|
367
|
+
sharedObject(tx, "pool", options.pool, true),
|
|
368
|
+
tx.add(feeSplit),
|
|
369
|
+
tx.object.clock(),
|
|
370
|
+
],
|
|
371
|
+
});
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/** Bluefin counterpart of `settleAndUpdateCetusFeeSplit`. */
|
|
376
|
+
settleAndUpdateBluefinFeeSplit(
|
|
377
|
+
options: LaunchTypes & {
|
|
378
|
+
vault: SharedObjectReference<true>;
|
|
379
|
+
launch: SharedObjectReference;
|
|
380
|
+
curveFeeCap: TransactionObjectInput;
|
|
381
|
+
memeCurrency: SharedObjectReference<true>;
|
|
382
|
+
bluefinConfig: SharedObjectReference<false>;
|
|
383
|
+
pool: SharedObjectReference<true>;
|
|
384
|
+
feeSplit: FeeSplit;
|
|
385
|
+
},
|
|
386
|
+
) {
|
|
387
|
+
const types = normalizeLaunchTypes(options);
|
|
388
|
+
const feeSplit = this.launchpad.feeSplit(options.feeSplit);
|
|
389
|
+
return (tx: Transaction): void => {
|
|
390
|
+
tx.moveCall({
|
|
391
|
+
target: `${this.deployment.packageId}::bluefin::settle_and_update_fee_split`,
|
|
392
|
+
typeArguments: [types.memeType, types.quoteType],
|
|
393
|
+
arguments: [
|
|
394
|
+
sharedObject(tx, "vault", options.vault, true),
|
|
395
|
+
this.#migratorsVersion(tx),
|
|
396
|
+
this.#lpFeePolicy(tx),
|
|
397
|
+
sharedObject(tx, "launch", options.launch, options.launch.mutable),
|
|
398
|
+
tx.object(options.curveFeeCap),
|
|
399
|
+
sharedObject(tx, "memeCurrency", options.memeCurrency, true),
|
|
400
|
+
sharedObject(tx, "bluefinConfig", options.bluefinConfig, false),
|
|
401
|
+
sharedObject(tx, "pool", options.pool, true),
|
|
402
|
+
tx.add(feeSplit),
|
|
403
|
+
tx.object.clock(),
|
|
404
|
+
],
|
|
405
|
+
});
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Swaps `quoteIn` atomic units of the vault's burn Quote for Meme in its
|
|
411
|
+
* Cetus pool and burns it, under a `BuybackAdmin` witness. The contract
|
|
412
|
+
* aborts with `EBuybackQuoteOutOfRange` when `quoteIn` exceeds the vault's
|
|
413
|
+
* burn Quote, and unless the swap returns at least `minMemeOut`; set it from
|
|
414
|
+
* an off-chain price, since anyone can move the pool's price within a
|
|
415
|
+
* transaction. Unspent Quote waits for the next buyback.
|
|
416
|
+
*/
|
|
417
|
+
buybackAndBurnCetus(
|
|
418
|
+
options: LaunchTypes &
|
|
419
|
+
CetusObjects & {
|
|
420
|
+
memeSide: CetusMemeSide;
|
|
421
|
+
vault: SharedObjectReference<true>;
|
|
422
|
+
adminWitness: TransactionObjectInput;
|
|
423
|
+
memeCurrency: SharedObjectReference<true>;
|
|
424
|
+
pool: SharedObjectReference<true>;
|
|
425
|
+
quoteIn: bigint;
|
|
426
|
+
minMemeOut: bigint;
|
|
427
|
+
},
|
|
428
|
+
) {
|
|
429
|
+
const types = normalizeLaunchTypes(options);
|
|
430
|
+
const memeSide = normalizeMemeSide(options.memeSide);
|
|
431
|
+
const quoteIn = requirePositiveU64("quoteIn", options.quoteIn);
|
|
432
|
+
const minMemeOut = requireU64("minMemeOut", options.minMemeOut);
|
|
433
|
+
return (tx: Transaction): void => {
|
|
434
|
+
tx.moveCall({
|
|
435
|
+
target: `${this.deployment.packageId}::cetus::buyback_and_burn`,
|
|
436
|
+
typeArguments: cetusTypeArguments(types, memeSide),
|
|
437
|
+
arguments: [
|
|
438
|
+
sharedObject(tx, "vault", options.vault, true),
|
|
439
|
+
this.#migratorsVersion(tx),
|
|
440
|
+
tx.object(options.adminWitness),
|
|
441
|
+
sharedObject(tx, "memeCurrency", options.memeCurrency, true),
|
|
442
|
+
sharedObject(tx, "cetusConfig", options.cetusConfig, false),
|
|
443
|
+
sharedObject(tx, "pool", options.pool, true),
|
|
444
|
+
tx.pure.u64(quoteIn),
|
|
445
|
+
tx.pure.u64(minMemeOut),
|
|
446
|
+
tx.object.clock(),
|
|
447
|
+
],
|
|
448
|
+
});
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/** Bluefin counterpart of `buybackAndBurnCetus`. */
|
|
453
|
+
buybackAndBurnBluefin(
|
|
454
|
+
options: LaunchTypes & {
|
|
455
|
+
vault: SharedObjectReference<true>;
|
|
456
|
+
adminWitness: TransactionObjectInput;
|
|
457
|
+
memeCurrency: SharedObjectReference<true>;
|
|
458
|
+
bluefinConfig: SharedObjectReference<false>;
|
|
459
|
+
pool: SharedObjectReference<true>;
|
|
460
|
+
quoteIn: bigint;
|
|
461
|
+
minMemeOut: bigint;
|
|
462
|
+
},
|
|
463
|
+
) {
|
|
464
|
+
const types = normalizeLaunchTypes(options);
|
|
465
|
+
const quoteIn = requirePositiveU64("quoteIn", options.quoteIn);
|
|
466
|
+
const minMemeOut = requireU64("minMemeOut", options.minMemeOut);
|
|
467
|
+
return (tx: Transaction): void => {
|
|
468
|
+
tx.moveCall({
|
|
469
|
+
target: `${this.deployment.packageId}::bluefin::buyback_and_burn`,
|
|
470
|
+
typeArguments: [types.memeType, types.quoteType],
|
|
471
|
+
arguments: [
|
|
472
|
+
sharedObject(tx, "vault", options.vault, true),
|
|
473
|
+
this.#migratorsVersion(tx),
|
|
474
|
+
tx.object(options.adminWitness),
|
|
475
|
+
sharedObject(tx, "memeCurrency", options.memeCurrency, true),
|
|
476
|
+
sharedObject(tx, "bluefinConfig", options.bluefinConfig, false),
|
|
477
|
+
sharedObject(tx, "pool", options.pool, true),
|
|
478
|
+
tx.pure.u64(quoteIn),
|
|
479
|
+
tx.pure.u64(minMemeOut),
|
|
480
|
+
tx.object.clock(),
|
|
481
|
+
],
|
|
482
|
+
});
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Claims the creator's accrued LP fees with the launch's live `CurveFeeCap`.
|
|
488
|
+
* `launch` is read immutably by Move.
|
|
489
|
+
*/
|
|
490
|
+
claimCreatorFees(
|
|
491
|
+
options: LaunchTypes & {
|
|
492
|
+
vault: SharedObjectReference<true>;
|
|
493
|
+
launch: SharedObjectReference;
|
|
494
|
+
curveFeeCap: TransactionObjectInput;
|
|
495
|
+
},
|
|
496
|
+
) {
|
|
497
|
+
const types = normalizeLaunchTypes(options);
|
|
498
|
+
return (tx: Transaction): TransactionResult =>
|
|
499
|
+
tx.moveCall({
|
|
500
|
+
target: `${this.deployment.packageId}::vault::claim_creator_fees`,
|
|
501
|
+
typeArguments: [types.memeType, types.quoteType],
|
|
502
|
+
arguments: [
|
|
503
|
+
sharedObject(tx, "vault", options.vault, true),
|
|
504
|
+
this.#migratorsVersion(tx),
|
|
505
|
+
sharedObject(tx, "launch", options.launch, options.launch.mutable),
|
|
506
|
+
tx.object(options.curveFeeCap),
|
|
507
|
+
],
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* `vault::claim_protocol_lp_fees_with_partner`: pays a partnered vault's held
|
|
513
|
+
* Blast LP fees, the launch's partner its cut in force of each asset, rounded
|
|
514
|
+
* down, and the `LpFeePolicy` destination the rest. Anyone may call it;
|
|
515
|
+
* holding nothing pays nothing.
|
|
516
|
+
*/
|
|
517
|
+
claimProtocolLpFeesWithPartner(
|
|
518
|
+
options: LaunchTypes & {
|
|
519
|
+
vault: SharedObjectReference<true>;
|
|
520
|
+
partner: SharedObjectReference<false>;
|
|
521
|
+
},
|
|
522
|
+
) {
|
|
523
|
+
const types = normalizeLaunchTypes(options);
|
|
524
|
+
return (tx: Transaction): void => {
|
|
525
|
+
tx.moveCall({
|
|
526
|
+
target: `${this.deployment.packageId}::vault::claim_protocol_lp_fees_with_partner`,
|
|
527
|
+
typeArguments: [types.memeType, types.quoteType],
|
|
528
|
+
arguments: [
|
|
529
|
+
sharedObject(tx, "vault", options.vault, true),
|
|
530
|
+
this.#migratorsVersion(tx),
|
|
531
|
+
this.#lpFeePolicy(tx),
|
|
532
|
+
sharedObject(tx, "partner", options.partner, false),
|
|
533
|
+
tx.object.clock(),
|
|
534
|
+
],
|
|
535
|
+
});
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/** Claims the protocol-owned migration residuals under a `TreasuryAdmin` witness. */
|
|
540
|
+
claimProtocolFees(
|
|
541
|
+
options: LaunchTypes & {
|
|
542
|
+
vault: SharedObjectReference<true>;
|
|
543
|
+
adminWitness: TransactionObjectInput;
|
|
544
|
+
},
|
|
545
|
+
) {
|
|
546
|
+
const types = normalizeLaunchTypes(options);
|
|
547
|
+
return (tx: Transaction): TransactionResult =>
|
|
548
|
+
tx.moveCall({
|
|
549
|
+
target: `${this.deployment.packageId}::vault::claim_protocol_fees`,
|
|
550
|
+
typeArguments: [types.memeType, types.quoteType],
|
|
551
|
+
arguments: [
|
|
552
|
+
sharedObject(tx, "vault", options.vault, true),
|
|
553
|
+
this.#migratorsVersion(tx),
|
|
554
|
+
tx.object(options.adminWitness),
|
|
555
|
+
],
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/** Changes Blast's default Meme and Quote LP-fee shares for coins without their own pair (`FeeAdmin`). */
|
|
560
|
+
setLpFeeDefaultShares(options: {
|
|
561
|
+
adminWitness: TransactionObjectInput;
|
|
562
|
+
memeBps: bigint;
|
|
563
|
+
quoteBps: bigint;
|
|
564
|
+
}) {
|
|
565
|
+
return this.#lpFeePolicyAdmin("set_default_shares", [], options, (tx) => [
|
|
566
|
+
tx.add(this.launchpad.bps(options.memeBps)),
|
|
567
|
+
tx.add(this.launchpad.bps(options.quoteBps)),
|
|
568
|
+
]);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/** Sets Blast's LP-fee shares for one original Meme type (`FeeAdmin`). */
|
|
572
|
+
setLpFeeCoinShares(options: {
|
|
573
|
+
memeType: string;
|
|
574
|
+
adminWitness: TransactionObjectInput;
|
|
575
|
+
memeBps: bigint;
|
|
576
|
+
quoteBps: bigint;
|
|
577
|
+
}) {
|
|
578
|
+
return this.#lpFeePolicyAdmin(
|
|
579
|
+
"set_coin_shares",
|
|
580
|
+
[normalizeStructTag(options.memeType)],
|
|
581
|
+
options,
|
|
582
|
+
(tx) => [
|
|
583
|
+
tx.add(this.launchpad.bps(options.memeBps)),
|
|
584
|
+
tx.add(this.launchpad.bps(options.quoteBps)),
|
|
585
|
+
],
|
|
586
|
+
);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/** Removes one Meme type's own pair so its collections use the defaults again (`FeeAdmin`). */
|
|
590
|
+
clearLpFeeCoinShares(options: {
|
|
591
|
+
memeType: string;
|
|
592
|
+
adminWitness: TransactionObjectInput;
|
|
593
|
+
}) {
|
|
594
|
+
return this.#lpFeePolicyAdmin(
|
|
595
|
+
"clear_coin_shares",
|
|
596
|
+
[normalizeStructTag(options.memeType)],
|
|
597
|
+
options,
|
|
598
|
+
() => [],
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/** Redirects every later protocol LP-fee payout (`TreasuryAdmin`). */
|
|
603
|
+
setLpFeeProtocolDestination(options: {
|
|
604
|
+
adminWitness: TransactionObjectInput;
|
|
605
|
+
destination: string;
|
|
606
|
+
}) {
|
|
607
|
+
const destination = normalizeSuiAddress(options.destination);
|
|
608
|
+
return this.#lpFeePolicyAdmin(
|
|
609
|
+
"set_protocol_destination",
|
|
610
|
+
[],
|
|
611
|
+
options,
|
|
612
|
+
(tx) => [tx.pure.address(destination)],
|
|
613
|
+
);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Publishes a holder-reward round from a validated manifest, reserving its
|
|
618
|
+
* budget from the vault's rewards balance, and shares the `Round`
|
|
619
|
+
* (`RewardsAdmin`).
|
|
620
|
+
*/
|
|
621
|
+
publishHolderRewardRound(
|
|
622
|
+
options: LaunchTypes & {
|
|
623
|
+
vault: SharedObjectReference<true>;
|
|
624
|
+
adminWitness: TransactionObjectInput;
|
|
625
|
+
manifest: RewardManifest;
|
|
626
|
+
},
|
|
627
|
+
) {
|
|
628
|
+
const types = normalizeLaunchTypes(options);
|
|
629
|
+
const manifest = validateRewardManifest(
|
|
630
|
+
options.manifest,
|
|
631
|
+
MIGRATOR_REWARD_LEAF_DOMAIN,
|
|
632
|
+
);
|
|
633
|
+
if (
|
|
634
|
+
rewardAddress(manifest.vaultId) !== rewardAddress(options.vault.objectId)
|
|
635
|
+
) {
|
|
636
|
+
throw new TypeError("manifest belongs to another vault");
|
|
637
|
+
}
|
|
638
|
+
return (tx: Transaction): void => {
|
|
639
|
+
tx.moveCall({
|
|
640
|
+
target: `${this.deployment.packageId}::blast_holder_rewards::publish_round`,
|
|
641
|
+
typeArguments: [types.memeType, types.quoteType],
|
|
642
|
+
arguments: [
|
|
643
|
+
sharedObject(tx, "vault", options.vault, true),
|
|
644
|
+
this.#migratorsVersion(tx),
|
|
645
|
+
tx.object(options.adminWitness),
|
|
646
|
+
tx.pure.u64(manifest.number),
|
|
647
|
+
tx.pure.u64(manifest.startCheckpoint),
|
|
648
|
+
tx.pure.u64(manifest.endCheckpoint),
|
|
649
|
+
tx.pure.vector("u8", rewardDigest(manifest.root)),
|
|
650
|
+
tx.pure.vector("u8", rewardDigest(manifest.manifestDigest)),
|
|
651
|
+
tx.pure.u64(manifest.allocations.length),
|
|
652
|
+
tx.pure.u64(manifest.memeAmount),
|
|
653
|
+
tx.pure.u64(manifest.quoteAmount),
|
|
654
|
+
],
|
|
655
|
+
});
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/** Relays one allocation's proof; the round pays its committed beneficiary. */
|
|
660
|
+
claimHolderReward(
|
|
661
|
+
options: LaunchTypes & {
|
|
662
|
+
round: SharedObjectReference<true>;
|
|
663
|
+
allocation: RewardProof;
|
|
664
|
+
},
|
|
665
|
+
) {
|
|
666
|
+
const types = normalizeLaunchTypes(options);
|
|
667
|
+
const { allocation } = options;
|
|
668
|
+
const index = requireU64("index", BigInt(allocation.index));
|
|
669
|
+
const memeAmount = requireU64("memeAmount", BigInt(allocation.memeAmount));
|
|
670
|
+
const quoteAmount = requireU64(
|
|
671
|
+
"quoteAmount",
|
|
672
|
+
BigInt(allocation.quoteAmount),
|
|
673
|
+
);
|
|
674
|
+
const beneficiary = rewardAddress(allocation.beneficiary);
|
|
675
|
+
if (allocation.proof.length > MAX_HOLDER_REWARD_PROOF_DEPTH) {
|
|
676
|
+
throw new RangeError(
|
|
677
|
+
`proof exceeds ${MAX_HOLDER_REWARD_PROOF_DEPTH} siblings`,
|
|
678
|
+
);
|
|
679
|
+
}
|
|
680
|
+
const proof = allocation.proof.map((sibling) =>
|
|
681
|
+
Array.from(rewardDigest(sibling)),
|
|
682
|
+
);
|
|
683
|
+
return (tx: Transaction): void => {
|
|
684
|
+
tx.moveCall({
|
|
685
|
+
target: `${this.deployment.packageId}::blast_holder_rewards::claim`,
|
|
686
|
+
typeArguments: [types.memeType, types.quoteType],
|
|
687
|
+
arguments: [
|
|
688
|
+
sharedObject(tx, "round", options.round, true),
|
|
689
|
+
this.#migratorsVersion(tx),
|
|
690
|
+
tx.pure.u64(index),
|
|
691
|
+
tx.pure.address(beneficiary),
|
|
692
|
+
tx.pure.u64(memeAmount),
|
|
693
|
+
tx.pure.u64(quoteAmount),
|
|
694
|
+
tx.pure.vector("vector<u8>", proof),
|
|
695
|
+
],
|
|
696
|
+
});
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
#lpFeePolicyAdmin(
|
|
701
|
+
functionName: string,
|
|
702
|
+
typeArguments: string[],
|
|
703
|
+
options: { adminWitness: TransactionObjectInput },
|
|
704
|
+
extra: (tx: Transaction) => TransactionArgument[],
|
|
705
|
+
) {
|
|
706
|
+
return (tx: Transaction): void => {
|
|
707
|
+
tx.moveCall({
|
|
708
|
+
target: `${this.deployment.packageId}::lp_fee_policy::${functionName}`,
|
|
709
|
+
typeArguments,
|
|
710
|
+
arguments: [
|
|
711
|
+
deploymentObject(tx, this.deployment.lpFeePolicy, true),
|
|
712
|
+
this.#migratorsVersion(tx),
|
|
713
|
+
tx.object(options.adminWitness),
|
|
714
|
+
...extra(tx),
|
|
715
|
+
],
|
|
716
|
+
});
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
#migratorsVersion(tx: Transaction): TransactionObjectArgument {
|
|
721
|
+
return deploymentObject(tx, this.deployment.migratorsVersion, false);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
#launchpadVersion(tx: Transaction): TransactionObjectArgument {
|
|
725
|
+
return deploymentObject(
|
|
726
|
+
tx,
|
|
727
|
+
this.deployment.launchpad.packageVersion,
|
|
728
|
+
false,
|
|
729
|
+
);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
#launchConfig(tx: Transaction): TransactionObjectArgument {
|
|
733
|
+
return deploymentObject(tx, this.deployment.launchpad.launchConfig, false);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
#lpFeePolicy(tx: Transaction): TransactionObjectArgument {
|
|
737
|
+
return deploymentObject(tx, this.deployment.lpFeePolicy, false);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
export class MigratorTransactions {
|
|
742
|
+
readonly call: MigratorCalls;
|
|
743
|
+
readonly #useGasCoin: boolean;
|
|
744
|
+
|
|
745
|
+
constructor(
|
|
746
|
+
deployment: MigratorsDeployment,
|
|
747
|
+
options: CoinSourceOptions = {},
|
|
748
|
+
) {
|
|
749
|
+
this.call = new MigratorCalls(deployment);
|
|
750
|
+
this.#useGasCoin = options.useGasCoin ?? true;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Starts, configures, finalizes, and shares a Cetus launch atomically, with
|
|
755
|
+
* an optional purchase on the owned launch, routed to its recipient.
|
|
756
|
+
*/
|
|
757
|
+
createCetusLaunch(
|
|
758
|
+
options: CreateLaunchOptions &
|
|
759
|
+
CetusObjects & {
|
|
760
|
+
cetusPools: SharedObjectReference<true>;
|
|
761
|
+
tickSpacing: number;
|
|
762
|
+
},
|
|
763
|
+
): Transaction {
|
|
764
|
+
const tx = new Transaction();
|
|
765
|
+
const initializer = tx.add(this.call.newCetusLaunch(options));
|
|
766
|
+
addLaunchCompletion(tx, this.call.launchpad, {
|
|
767
|
+
...options,
|
|
768
|
+
initializer,
|
|
769
|
+
currency: options.memeCurrency,
|
|
770
|
+
useGasCoin: options.useGasCoin ?? this.#useGasCoin,
|
|
771
|
+
});
|
|
772
|
+
return tx;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/** Bluefin counterpart of `createCetusLaunch`. */
|
|
776
|
+
createBluefinLaunch(
|
|
777
|
+
options: CreateLaunchOptions & { tickSpacing: number; feeRate: bigint },
|
|
778
|
+
): Transaction {
|
|
779
|
+
const tx = new Transaction();
|
|
780
|
+
const initializer = tx.add(this.call.newBluefinLaunch(options));
|
|
781
|
+
addLaunchCompletion(tx, this.call.launchpad, {
|
|
782
|
+
...options,
|
|
783
|
+
initializer,
|
|
784
|
+
currency: options.memeCurrency,
|
|
785
|
+
useGasCoin: options.useGasCoin ?? this.#useGasCoin,
|
|
786
|
+
});
|
|
787
|
+
return tx;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
migrateCetus(
|
|
791
|
+
options: Parameters<MigratorCalls["migrateCetus"]>[0],
|
|
792
|
+
): Transaction {
|
|
793
|
+
const tx = new Transaction();
|
|
794
|
+
tx.add(this.call.migrateCetus(options));
|
|
795
|
+
return tx;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
/** Pays Bluefin's SUI pool-creation fee as an exact-balance coin. */
|
|
799
|
+
migrateBluefin(
|
|
800
|
+
options: Omit<
|
|
801
|
+
Parameters<MigratorCalls["migrateBluefin"]>[0],
|
|
802
|
+
"creationFee"
|
|
803
|
+
> & {
|
|
804
|
+
creationFee: bigint;
|
|
805
|
+
} & CoinSourceOptions,
|
|
806
|
+
): Transaction {
|
|
807
|
+
requireU64("creationFee", options.creationFee);
|
|
808
|
+
const tx = new Transaction();
|
|
809
|
+
const creationFee = tx.coin({
|
|
810
|
+
type: "0x2::sui::SUI",
|
|
811
|
+
balance: options.creationFee,
|
|
812
|
+
useGasCoin: options.useGasCoin ?? this.#useGasCoin,
|
|
813
|
+
});
|
|
814
|
+
tx.add(this.call.migrateBluefin({ ...options, creationFee }));
|
|
815
|
+
return tx;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
/** Then pays the vault's partner when `partner` is given; see `claimProtocolLpFeesWithPartner`. */
|
|
819
|
+
collectCetusFees(
|
|
820
|
+
options: Parameters<MigratorCalls["collectCetusFees"]>[0] & LpFeePartner,
|
|
821
|
+
): Transaction {
|
|
822
|
+
const tx = new Transaction();
|
|
823
|
+
tx.add(this.call.collectCetusFees(options));
|
|
824
|
+
return this.#claimProtocolLpFeesWithPartnerAfter(tx, options);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
/** Then pays the vault's partner when `partner` is given; see `claimProtocolLpFeesWithPartner`. */
|
|
828
|
+
collectBluefinFees(
|
|
829
|
+
options: Parameters<MigratorCalls["collectBluefinFees"]>[0] & LpFeePartner,
|
|
830
|
+
): Transaction {
|
|
831
|
+
const tx = new Transaction();
|
|
832
|
+
tx.add(this.call.collectBluefinFees(options));
|
|
833
|
+
return this.#claimProtocolLpFeesWithPartnerAfter(tx, options);
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/** Pays a partnered vault's partner and Blast the LP fees its collections held. */
|
|
837
|
+
claimProtocolLpFeesWithPartner(
|
|
838
|
+
options: Parameters<MigratorCalls["claimProtocolLpFeesWithPartner"]>[0],
|
|
839
|
+
): Transaction {
|
|
840
|
+
const tx = new Transaction();
|
|
841
|
+
tx.add(this.call.claimProtocolLpFeesWithPartner(options));
|
|
842
|
+
return tx;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
settleAndUpdateCetusFeeSplit(
|
|
846
|
+
options: Omit<
|
|
847
|
+
Parameters<MigratorCalls["settleAndUpdateCetusFeeSplit"]>[0],
|
|
848
|
+
"curveFeeCap"
|
|
849
|
+
> & { curveFeeCapId: string },
|
|
850
|
+
): Transaction {
|
|
851
|
+
const tx = new Transaction();
|
|
852
|
+
tx.add(
|
|
853
|
+
this.call.settleAndUpdateCetusFeeSplit({
|
|
854
|
+
...options,
|
|
855
|
+
curveFeeCap: options.curveFeeCapId,
|
|
856
|
+
}),
|
|
857
|
+
);
|
|
858
|
+
return tx;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
settleAndUpdateBluefinFeeSplit(
|
|
862
|
+
options: Omit<
|
|
863
|
+
Parameters<MigratorCalls["settleAndUpdateBluefinFeeSplit"]>[0],
|
|
864
|
+
"curveFeeCap"
|
|
865
|
+
> & { curveFeeCapId: string },
|
|
866
|
+
): Transaction {
|
|
867
|
+
const tx = new Transaction();
|
|
868
|
+
tx.add(
|
|
869
|
+
this.call.settleAndUpdateBluefinFeeSplit({
|
|
870
|
+
...options,
|
|
871
|
+
curveFeeCap: options.curveFeeCapId,
|
|
872
|
+
}),
|
|
873
|
+
);
|
|
874
|
+
return tx;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
claimCreatorFees(
|
|
878
|
+
options: LaunchTypes & {
|
|
879
|
+
vault: SharedObjectReference<true>;
|
|
880
|
+
launch: SharedObjectReference;
|
|
881
|
+
curveFeeCapId: string;
|
|
882
|
+
recipient: string;
|
|
883
|
+
},
|
|
884
|
+
): Transaction {
|
|
885
|
+
const tx = new Transaction();
|
|
886
|
+
const result = tx.add(
|
|
887
|
+
this.call.claimCreatorFees({
|
|
888
|
+
...options,
|
|
889
|
+
curveFeeCap: options.curveFeeCapId,
|
|
890
|
+
}),
|
|
891
|
+
);
|
|
892
|
+
tx.transferObjects(
|
|
893
|
+
moveResults(result, 2),
|
|
894
|
+
normalizeSuiAddress(options.recipient),
|
|
895
|
+
);
|
|
896
|
+
return tx;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
claimProtocolFees(
|
|
900
|
+
options: LaunchTypes & {
|
|
901
|
+
vault: SharedObjectReference<true>;
|
|
902
|
+
adminCapId: string;
|
|
903
|
+
recipient: string;
|
|
904
|
+
},
|
|
905
|
+
): Transaction {
|
|
906
|
+
const tx = new Transaction();
|
|
907
|
+
const adminWitness = tx.add(
|
|
908
|
+
this.call.signIn({ adminCap: options.adminCapId, role: "TreasuryAdmin" }),
|
|
909
|
+
);
|
|
910
|
+
const result = tx.add(
|
|
911
|
+
this.call.claimProtocolFees({ ...options, adminWitness }),
|
|
912
|
+
);
|
|
913
|
+
tx.transferObjects(
|
|
914
|
+
moveResults(result, 2),
|
|
915
|
+
normalizeSuiAddress(options.recipient),
|
|
916
|
+
);
|
|
917
|
+
return tx;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
setLpFeeDefaultShares(options: {
|
|
921
|
+
adminCapId: string;
|
|
922
|
+
memeBps: bigint;
|
|
923
|
+
quoteBps: bigint;
|
|
924
|
+
}): Transaction {
|
|
925
|
+
return this.#asAdmin(options.adminCapId, "FeeAdmin", (adminWitness) =>
|
|
926
|
+
this.call.setLpFeeDefaultShares({ ...options, adminWitness }),
|
|
927
|
+
);
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
setLpFeeCoinShares(options: {
|
|
931
|
+
memeType: string;
|
|
932
|
+
adminCapId: string;
|
|
933
|
+
memeBps: bigint;
|
|
934
|
+
quoteBps: bigint;
|
|
935
|
+
}): Transaction {
|
|
936
|
+
return this.#asAdmin(options.adminCapId, "FeeAdmin", (adminWitness) =>
|
|
937
|
+
this.call.setLpFeeCoinShares({ ...options, adminWitness }),
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
clearLpFeeCoinShares(options: {
|
|
942
|
+
memeType: string;
|
|
943
|
+
adminCapId: string;
|
|
944
|
+
}): Transaction {
|
|
945
|
+
return this.#asAdmin(options.adminCapId, "FeeAdmin", (adminWitness) =>
|
|
946
|
+
this.call.clearLpFeeCoinShares({ ...options, adminWitness }),
|
|
947
|
+
);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
setLpFeeProtocolDestination(options: {
|
|
951
|
+
adminCapId: string;
|
|
952
|
+
destination: string;
|
|
953
|
+
}): Transaction {
|
|
954
|
+
return this.#asAdmin(options.adminCapId, "TreasuryAdmin", (adminWitness) =>
|
|
955
|
+
this.call.setLpFeeProtocolDestination({ ...options, adminWitness }),
|
|
956
|
+
);
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
buybackAndBurnCetus(
|
|
960
|
+
options: Omit<
|
|
961
|
+
Parameters<MigratorCalls["buybackAndBurnCetus"]>[0],
|
|
962
|
+
"adminWitness"
|
|
963
|
+
> & { adminCapId: string },
|
|
964
|
+
): Transaction {
|
|
965
|
+
return this.#asAdmin(options.adminCapId, "BuybackAdmin", (adminWitness) =>
|
|
966
|
+
this.call.buybackAndBurnCetus({ ...options, adminWitness }),
|
|
967
|
+
);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
buybackAndBurnBluefin(
|
|
971
|
+
options: Omit<
|
|
972
|
+
Parameters<MigratorCalls["buybackAndBurnBluefin"]>[0],
|
|
973
|
+
"adminWitness"
|
|
974
|
+
> & { adminCapId: string },
|
|
975
|
+
): Transaction {
|
|
976
|
+
return this.#asAdmin(options.adminCapId, "BuybackAdmin", (adminWitness) =>
|
|
977
|
+
this.call.buybackAndBurnBluefin({ ...options, adminWitness }),
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
publishHolderRewardRound(
|
|
982
|
+
options: Omit<
|
|
983
|
+
Parameters<MigratorCalls["publishHolderRewardRound"]>[0],
|
|
984
|
+
"adminWitness"
|
|
985
|
+
> & { adminCapId: string },
|
|
986
|
+
): Transaction {
|
|
987
|
+
return this.#asAdmin(options.adminCapId, "RewardsAdmin", (adminWitness) =>
|
|
988
|
+
this.call.publishHolderRewardRound({ ...options, adminWitness }),
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
/** Relays up to `allocations.length` proofs of one round in a single PTB. */
|
|
993
|
+
claimHolderRewards(
|
|
994
|
+
options: LaunchTypes & {
|
|
995
|
+
round: SharedObjectReference<true>;
|
|
996
|
+
allocations: readonly RewardProof[];
|
|
997
|
+
},
|
|
998
|
+
): Transaction {
|
|
999
|
+
const tx = new Transaction();
|
|
1000
|
+
for (const allocation of options.allocations) {
|
|
1001
|
+
tx.add(this.call.claimHolderReward({ ...options, allocation }));
|
|
1002
|
+
}
|
|
1003
|
+
return tx;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
#asAdmin(
|
|
1007
|
+
adminCapId: string,
|
|
1008
|
+
role: BlastFunAdminRole,
|
|
1009
|
+
call: (
|
|
1010
|
+
adminWitness: TransactionObjectArgument,
|
|
1011
|
+
) => (tx: Transaction) => void,
|
|
1012
|
+
): Transaction {
|
|
1013
|
+
const tx = new Transaction();
|
|
1014
|
+
const adminWitness = tx.add(
|
|
1015
|
+
this.call.signIn({ adminCap: adminCapId, role }),
|
|
1016
|
+
);
|
|
1017
|
+
tx.add(call(adminWitness));
|
|
1018
|
+
return tx;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
#claimProtocolLpFeesWithPartnerAfter(
|
|
1022
|
+
tx: Transaction,
|
|
1023
|
+
options: LaunchTypes & {
|
|
1024
|
+
vault: SharedObjectReference<true>;
|
|
1025
|
+
} & LpFeePartner,
|
|
1026
|
+
): Transaction {
|
|
1027
|
+
const { partner } = options;
|
|
1028
|
+
if (partner)
|
|
1029
|
+
tx.add(this.call.claimProtocolLpFeesWithPartner({ ...options, partner }));
|
|
1030
|
+
return tx;
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
function sharedObject<const Mutable extends boolean>(
|
|
1035
|
+
tx: Transaction,
|
|
1036
|
+
name: string,
|
|
1037
|
+
reference: SharedObjectReference<Mutable>,
|
|
1038
|
+
mutable: Mutable,
|
|
1039
|
+
): TransactionObjectArgument {
|
|
1040
|
+
return tx.sharedObjectRef(
|
|
1041
|
+
normalizeSharedObjectReference(name, reference, mutable),
|
|
1042
|
+
);
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
/** `[Meme, Quote, CoinA, CoinB]`, the pool's coins in Cetus order. */
|
|
1046
|
+
function cetusTypeArguments(
|
|
1047
|
+
types: LaunchTypes,
|
|
1048
|
+
memeSide: CetusMemeSide,
|
|
1049
|
+
): string[] {
|
|
1050
|
+
const { memeType, quoteType } = types;
|
|
1051
|
+
return memeSide === "a"
|
|
1052
|
+
? [memeType, quoteType, memeType, quoteType]
|
|
1053
|
+
: [memeType, quoteType, quoteType, memeType];
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
function normalizeMemeSide(value: CetusMemeSide): CetusMemeSide {
|
|
1057
|
+
if (value !== "a" && value !== "b") {
|
|
1058
|
+
throw new RangeError("memeSide must be a or b");
|
|
1059
|
+
}
|
|
1060
|
+
return value;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
function requireU32(name: string, value: number): number {
|
|
1064
|
+
if (!Number.isInteger(value) || value < 0 || value > 0xffff_ffff) {
|
|
1065
|
+
throw new RangeError(`${name} must be a u32`);
|
|
1066
|
+
}
|
|
1067
|
+
return value;
|
|
1068
|
+
}
|