@meteora-ag/dynamic-bonding-curve-sdk 1.5.13 → 2.0.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.
@@ -0,0 +1,2024 @@
1
+ // src/types.ts
2
+ var ActivationType = /* @__PURE__ */ ((ActivationType2) => {
3
+ ActivationType2[ActivationType2["Slot"] = 0] = "Slot";
4
+ ActivationType2[ActivationType2["Timestamp"] = 1] = "Timestamp";
5
+ return ActivationType2;
6
+ })(ActivationType || {});
7
+ var TokenType = /* @__PURE__ */ ((TokenType2) => {
8
+ TokenType2[TokenType2["SPLToken"] = 0] = "SPLToken";
9
+ TokenType2[TokenType2["Token2022"] = 1] = "Token2022";
10
+ return TokenType2;
11
+ })(TokenType || {});
12
+ var CollectFeeMode = /* @__PURE__ */ ((CollectFeeMode2) => {
13
+ CollectFeeMode2[CollectFeeMode2["QuoteToken"] = 0] = "QuoteToken";
14
+ CollectFeeMode2[CollectFeeMode2["OutputToken"] = 1] = "OutputToken";
15
+ return CollectFeeMode2;
16
+ })(CollectFeeMode || {});
17
+ var MigratedCollectFeeMode = /* @__PURE__ */ ((MigratedCollectFeeMode2) => {
18
+ MigratedCollectFeeMode2[MigratedCollectFeeMode2["QuoteToken"] = 0] = "QuoteToken";
19
+ MigratedCollectFeeMode2[MigratedCollectFeeMode2["OutputToken"] = 1] = "OutputToken";
20
+ MigratedCollectFeeMode2[MigratedCollectFeeMode2["Compounding"] = 2] = "Compounding";
21
+ return MigratedCollectFeeMode2;
22
+ })(MigratedCollectFeeMode || {});
23
+ var DammV2DynamicFeeMode = /* @__PURE__ */ ((DammV2DynamicFeeMode2) => {
24
+ DammV2DynamicFeeMode2[DammV2DynamicFeeMode2["Disabled"] = 0] = "Disabled";
25
+ DammV2DynamicFeeMode2[DammV2DynamicFeeMode2["Enabled"] = 1] = "Enabled";
26
+ return DammV2DynamicFeeMode2;
27
+ })(DammV2DynamicFeeMode || {});
28
+ var DammV2BaseFeeMode = /* @__PURE__ */ ((DammV2BaseFeeMode2) => {
29
+ DammV2BaseFeeMode2[DammV2BaseFeeMode2["FeeTimeSchedulerLinear"] = 0] = "FeeTimeSchedulerLinear";
30
+ DammV2BaseFeeMode2[DammV2BaseFeeMode2["FeeTimeSchedulerExponential"] = 1] = "FeeTimeSchedulerExponential";
31
+ DammV2BaseFeeMode2[DammV2BaseFeeMode2["RateLimiter"] = 2] = "RateLimiter";
32
+ DammV2BaseFeeMode2[DammV2BaseFeeMode2["FeeMarketCapSchedulerLinear"] = 3] = "FeeMarketCapSchedulerLinear";
33
+ DammV2BaseFeeMode2[DammV2BaseFeeMode2["FeeMarketCapSchedulerExponential"] = 4] = "FeeMarketCapSchedulerExponential";
34
+ return DammV2BaseFeeMode2;
35
+ })(DammV2BaseFeeMode || {});
36
+ var MigrationOption = /* @__PURE__ */ ((MigrationOption2) => {
37
+ MigrationOption2[MigrationOption2["MET_DAMM"] = 0] = "MET_DAMM";
38
+ MigrationOption2[MigrationOption2["MET_DAMM_V2"] = 1] = "MET_DAMM_V2";
39
+ return MigrationOption2;
40
+ })(MigrationOption || {});
41
+ var BaseFeeMode = /* @__PURE__ */ ((BaseFeeMode2) => {
42
+ BaseFeeMode2[BaseFeeMode2["FeeSchedulerLinear"] = 0] = "FeeSchedulerLinear";
43
+ BaseFeeMode2[BaseFeeMode2["FeeSchedulerExponential"] = 1] = "FeeSchedulerExponential";
44
+ BaseFeeMode2[BaseFeeMode2["RateLimiter"] = 2] = "RateLimiter";
45
+ return BaseFeeMode2;
46
+ })(BaseFeeMode || {});
47
+ var MigrationFeeOption = /* @__PURE__ */ ((MigrationFeeOption2) => {
48
+ MigrationFeeOption2[MigrationFeeOption2["FixedBps25"] = 0] = "FixedBps25";
49
+ MigrationFeeOption2[MigrationFeeOption2["FixedBps30"] = 1] = "FixedBps30";
50
+ MigrationFeeOption2[MigrationFeeOption2["FixedBps100"] = 2] = "FixedBps100";
51
+ MigrationFeeOption2[MigrationFeeOption2["FixedBps200"] = 3] = "FixedBps200";
52
+ MigrationFeeOption2[MigrationFeeOption2["FixedBps400"] = 4] = "FixedBps400";
53
+ MigrationFeeOption2[MigrationFeeOption2["FixedBps600"] = 5] = "FixedBps600";
54
+ MigrationFeeOption2[MigrationFeeOption2["Customizable"] = 6] = "Customizable";
55
+ return MigrationFeeOption2;
56
+ })(MigrationFeeOption || {});
57
+ var TokenDecimal = /* @__PURE__ */ ((TokenDecimal2) => {
58
+ TokenDecimal2[TokenDecimal2["SIX"] = 6] = "SIX";
59
+ TokenDecimal2[TokenDecimal2["SEVEN"] = 7] = "SEVEN";
60
+ TokenDecimal2[TokenDecimal2["EIGHT"] = 8] = "EIGHT";
61
+ TokenDecimal2[TokenDecimal2["NINE"] = 9] = "NINE";
62
+ return TokenDecimal2;
63
+ })(TokenDecimal || {});
64
+ var TradeDirection = /* @__PURE__ */ ((TradeDirection3) => {
65
+ TradeDirection3[TradeDirection3["BaseToQuote"] = 0] = "BaseToQuote";
66
+ TradeDirection3[TradeDirection3["QuoteToBase"] = 1] = "QuoteToBase";
67
+ return TradeDirection3;
68
+ })(TradeDirection || {});
69
+ var Rounding = /* @__PURE__ */ ((Rounding2) => {
70
+ Rounding2[Rounding2["Up"] = 0] = "Up";
71
+ Rounding2[Rounding2["Down"] = 1] = "Down";
72
+ return Rounding2;
73
+ })(Rounding || {});
74
+ var TokenAuthorityOption = /* @__PURE__ */ ((TokenAuthorityOption2) => {
75
+ TokenAuthorityOption2[TokenAuthorityOption2["CreatorUpdateAuthority"] = 0] = "CreatorUpdateAuthority";
76
+ TokenAuthorityOption2[TokenAuthorityOption2["Immutable"] = 1] = "Immutable";
77
+ TokenAuthorityOption2[TokenAuthorityOption2["PartnerUpdateAuthority"] = 2] = "PartnerUpdateAuthority";
78
+ TokenAuthorityOption2[TokenAuthorityOption2["CreatorUpdateAndMintAuthority"] = 3] = "CreatorUpdateAndMintAuthority";
79
+ TokenAuthorityOption2[TokenAuthorityOption2["PartnerUpdateAndMintAuthority"] = 4] = "PartnerUpdateAndMintAuthority";
80
+ return TokenAuthorityOption2;
81
+ })(TokenAuthorityOption || {});
82
+ var SwapMode = /* @__PURE__ */ ((SwapMode2) => {
83
+ SwapMode2[SwapMode2["ExactIn"] = 0] = "ExactIn";
84
+ SwapMode2[SwapMode2["PartialFill"] = 1] = "PartialFill";
85
+ SwapMode2[SwapMode2["ExactOut"] = 2] = "ExactOut";
86
+ return SwapMode2;
87
+ })(SwapMode || {});
88
+ var TransferFeeWithheldAuthority = /* @__PURE__ */ ((TransferFeeWithheldAuthority2) => {
89
+ TransferFeeWithheldAuthority2[TransferFeeWithheldAuthority2["Partner"] = 0] = "Partner";
90
+ TransferFeeWithheldAuthority2[TransferFeeWithheldAuthority2["Creator"] = 1] = "Creator";
91
+ return TransferFeeWithheldAuthority2;
92
+ })(TransferFeeWithheldAuthority || {});
93
+ var MigratedTransferFeeAuthorityOption = /* @__PURE__ */ ((MigratedTransferFeeAuthorityOption2) => {
94
+ MigratedTransferFeeAuthorityOption2[MigratedTransferFeeAuthorityOption2["Immutable"] = 0] = "Immutable";
95
+ MigratedTransferFeeAuthorityOption2[MigratedTransferFeeAuthorityOption2["RevokeZeroFee"] = 1] = "RevokeZeroFee";
96
+ MigratedTransferFeeAuthorityOption2[MigratedTransferFeeAuthorityOption2["Creator"] = 2] = "Creator";
97
+ MigratedTransferFeeAuthorityOption2[MigratedTransferFeeAuthorityOption2["Partner"] = 3] = "Partner";
98
+ return MigratedTransferFeeAuthorityOption2;
99
+ })(MigratedTransferFeeAuthorityOption || {});
100
+ var AccountsType = {
101
+ TransferHookBase: {
102
+ transferHookBase: {}
103
+ },
104
+ TransferHookBaseReferral: {
105
+ transferHookBaseReferral: {}
106
+ }
107
+ };
108
+
109
+ // src/constants.ts
110
+ import BN from "bn.js";
111
+ import { PublicKey } from "@solana/web3.js";
112
+ var MAX_CURVE_POINT = 16;
113
+ var RESOLUTION = 64;
114
+ var ONE_Q64 = new BN(1).shln(RESOLUTION);
115
+ var FEE_DENOMINATOR = 1e9;
116
+ var MAX_BASIS_POINT = 1e4;
117
+ var MAX_BASE_TRANSFER_FEE_BPS = 1e3;
118
+ var LEGACY_CONFIG_VERSION = 0;
119
+ var U16_MAX = 65535;
120
+ var U24_MAX = 16777215;
121
+ var U64_MAX = new BN("18446744073709551615");
122
+ var U128_MAX = new BN("340282366920938463463374607431768211455");
123
+ var MIN_SQRT_PRICE = new BN("4295048016");
124
+ var MAX_SQRT_PRICE = new BN("79226673521066979257578248091");
125
+ var MIN_FEE_BPS = 25;
126
+ var MAX_FEE_BPS = 9900;
127
+ var MIN_FEE_NUMERATOR = 25e5;
128
+ var MAX_FEE_NUMERATOR = 99e7;
129
+ var MAX_RATE_LIMITER_DURATION_IN_SECONDS = 43200;
130
+ var MAX_RATE_LIMITER_DURATION_IN_SLOTS = 108e3;
131
+ var DYNAMIC_FEE_FILTER_PERIOD_DEFAULT = 10;
132
+ var DYNAMIC_FEE_DECAY_PERIOD_DEFAULT = 120;
133
+ var DYNAMIC_FEE_REDUCTION_FACTOR_DEFAULT = 5e3;
134
+ var DYNAMIC_FEE_SCALING_FACTOR = new BN(1e11);
135
+ var DYNAMIC_FEE_ROUNDING_OFFSET = new BN(99999999999);
136
+ var BIN_STEP_BPS_DEFAULT = 1;
137
+ var BIN_STEP_BPS_U128_DEFAULT = new BN("1844674407370955");
138
+ var MAX_PRICE_CHANGE_BPS_DEFAULT = 1500;
139
+ var MAX_DYNAMIC_FEE_PERCENT = 20;
140
+ var PROTOCOL_FEE_PERCENT = 20;
141
+ var PARTNER_AND_CREATOR_SURPLUS_SHARE = 80;
142
+ var HOST_FEE_PERCENT = 20;
143
+ var SWAP_BUFFER_PERCENTAGE = 25;
144
+ var PROTOCOL_LIQUIDITY_MIGRATION_FEE_BPS = 20;
145
+ var DAMM_V2_COMPOUNDING_DEAD_LIQUIDITY = new BN(100).shln(64);
146
+ var MAX_MIGRATION_FEE_PERCENTAGE = 99;
147
+ var MAX_CREATOR_MIGRATION_FEE_PERCENTAGE = 100;
148
+ var MIN_LOCKED_LIQUIDITY_BPS = 1e3;
149
+ var SECONDS_PER_DAY = 86400;
150
+ var MAX_LOCK_DURATION_IN_SECONDS = 63072e3;
151
+ var PROTOCOL_POOL_CREATION_FEE_PERCENT = 10;
152
+ var MIN_POOL_CREATION_FEE = 1e6;
153
+ var MAX_POOL_CREATION_FEE = 1e11;
154
+ var MIN_MIGRATED_POOL_FEE_BPS = 10;
155
+ var MAX_MIGRATED_POOL_FEE_BPS = 1e3;
156
+ var DYNAMIC_BONDING_CURVE_PROGRAM_ID = new PublicKey(
157
+ "dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN"
158
+ );
159
+ var METAPLEX_PROGRAM_ID = new PublicKey(
160
+ "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"
161
+ );
162
+ var DAMM_V1_PROGRAM_ID = new PublicKey(
163
+ "Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB"
164
+ );
165
+ var DAMM_V2_PROGRAM_ID = new PublicKey(
166
+ "cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG"
167
+ );
168
+ var VAULT_PROGRAM_ID = new PublicKey(
169
+ "24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi"
170
+ );
171
+ var LOCKER_PROGRAM_ID = new PublicKey(
172
+ "LocpQgucEQHbqNABEYvBvwoxCPsSbG91A1QaQhQQqjn"
173
+ );
174
+ var BASE_ADDRESS = new PublicKey(
175
+ "HWzXGcGHy4tcpYfaRDCyLNzXqBTv3E6BttpCH2vJxArv"
176
+ );
177
+ var DAMM_V1_MIGRATION_FEE_ADDRESS = [
178
+ new PublicKey("8f848CEy8eY6PhJ3VcemtBDzPPSD4Vq7aJczLZ3o8MmX"),
179
+ // FixedBps25
180
+ new PublicKey("HBxB8Lf14Yj8pqeJ8C4qDb5ryHL7xwpuykz31BLNYr7S"),
181
+ // FixedBps30
182
+ new PublicKey("7v5vBdUQHTNeqk1HnduiXcgbvCyVEZ612HLmYkQoAkik"),
183
+ // FixedBps100
184
+ new PublicKey("EkvP7d5yKxovj884d2DwmBQbrHUWRLGK6bympzrkXGja"),
185
+ // FixedBps200
186
+ new PublicKey("9EZYAJrcqNWNQzP2trzZesP7XKMHA1jEomHzbRsdX8R2"),
187
+ // FixedBps400
188
+ new PublicKey("8cdKo87jZU2R12KY1BUjjRPwyjgdNjLGqSGQyrDshhud")
189
+ // FixedBps600
190
+ ];
191
+ var DAMM_V2_MIGRATION_FEE_ADDRESS = [
192
+ new PublicKey("7F6dnUcRuyM2TwR8myT1dYypFXpPSxqwKNSFNkxyNESd"),
193
+ // FixedBps25
194
+ new PublicKey("2nHK1kju6XjphBLbNxpM5XRGFj7p9U8vvNzyZiha1z6k"),
195
+ // FixedBps30
196
+ new PublicKey("Hv8Lmzmnju6m7kcokVKvwqz7QPmdX9XfKjJsXz8RXcjp"),
197
+ // FixedBps100
198
+ new PublicKey("2c4cYd4reUYVRAB9kUUkrq55VPyy2FNQ3FDL4o12JXmq"),
199
+ // FixedBps200
200
+ new PublicKey("AkmQWebAwFvWk55wBoCr5D62C6VVDTzi84NJuD9H7cFD"),
201
+ // FixedBps400
202
+ new PublicKey("DbCRBj8McvPYHJG1ukj8RE15h2dCNUdTAESG49XpQ44u"),
203
+ // FixedBps600
204
+ new PublicKey("A8gMrEPJkacWkcb3DGwtJwTe16HktSEfvwtuDh2MCtck")
205
+ // Customizable
206
+ ];
207
+ var DEFAULT_MIGRATED_POOL_FEE_PARAMS = {
208
+ collectFeeMode: 0,
209
+ dynamicFee: 0,
210
+ poolFeeBps: 0
211
+ };
212
+ var DEFAULT_LIQUIDITY_VESTING_INFO_PARAMS = {
213
+ vestingPercentage: 0,
214
+ bpsPerPeriod: 0,
215
+ numberOfPeriods: 0,
216
+ cliffDurationFromMigrationTime: 0,
217
+ totalDuration: 0
218
+ };
219
+ var DEFAULT_MIGRATED_POOL_MARKET_CAP_FEE_SCHEDULER_PARAMS = {
220
+ numberOfPeriod: 0,
221
+ sqrtPriceStepBps: 0,
222
+ schedulerExpirationDuration: 0,
223
+ reductionFactor: new BN(0)
224
+ };
225
+
226
+ // src/math/errors.ts
227
+ var ProgramError = {
228
+ MathOverflow: "Math operation overflow",
229
+ ExceededSlippage: "Exceeded slippage tolerance",
230
+ ExceedMaxFeeBps: "Exceeded max fee bps",
231
+ AmountIsZero: "Amount is zero",
232
+ TypeCastFailed: "Type cast error",
233
+ InvalidActivationType: "Invalid activation type",
234
+ InvalidQuoteMint: "Invalid quote mint",
235
+ InvalidCollectFeeMode: "Invalid collect fee mode",
236
+ InvalidMigrationFeeOption: "Invalid migration fee option",
237
+ InvalidInput: "Invalid input",
238
+ NotEnoughLiquidity: "Not enough liquidity",
239
+ PoolIsCompleted: "Pool is completed",
240
+ InvalidMigrationOption: "Invalid migration option",
241
+ InvalidTokenDecimals: "Invalid token decimals",
242
+ InvalidTokenType: "Invalid token type",
243
+ InvalidQuoteThreshold: "Invalid quote threshold",
244
+ InvalidTokenSupply: "Invalid token supply",
245
+ InvalidCurve: "Invalid curve",
246
+ InvalidVestingParameters: "Invalid vesting parameters",
247
+ InsufficientLiquidity: "Liquidity in bonding curve is insufficient",
248
+ InvalidFeeScheduler: "Invalid fee scheduler",
249
+ InvalidCreatorTradingFeePercentage: "Invalid creator trading fee percentage",
250
+ InvalidBaseFeeMode: "Invalid base fee mode",
251
+ InvalidFeeRateLimiter: "Invalid fee rate limiter",
252
+ InvalidMigratedPoolFee: "Invalid migrated pool fee params",
253
+ // the program spells this "Undertermined error"
254
+ UndeterminedError: "Undetermined error",
255
+ AmountLeftIsNotZero: "Amount left is not zero",
256
+ InvalidPoolCreationFee: "Invalid pool creation fee",
257
+ InvalidFeeMarketCapScheduler: "Invalid fee market cap scheduler",
258
+ DeprecatedBaseFeeMode: "Deprecated base fee mode",
259
+ QuoteMintHasNonZeroTransferFee: "Quote mint has a non zero transfer fee or a live transfer fee config authority",
260
+ DeprecatedMigrationOption: "Deprecated migration option",
261
+ FeeInverseIsIncorrect: "Transfer fee inverse calculation is incorrect",
262
+ InvalidTransferFeeParameters: "Invalid transfer fee parameters",
263
+ ExceededInputAmount: "Required input amount exceeds the provided amount in",
264
+ InvalidFeeClaimer: "Invalid fee claimer"
265
+ };
266
+
267
+ // src/math/safeMath.ts
268
+ import BN2 from "bn.js";
269
+ var SafeMath = class {
270
+ static add(a, b) {
271
+ return a.add(b);
272
+ }
273
+ static sub(a, b) {
274
+ if (b.gt(a)) {
275
+ throw new Error(ProgramError.MathOverflow);
276
+ }
277
+ return a.sub(b);
278
+ }
279
+ static mul(a, b) {
280
+ return a.mul(b);
281
+ }
282
+ static div(a, b) {
283
+ if (b.isZero()) {
284
+ throw new Error(ProgramError.MathOverflow);
285
+ }
286
+ return a.div(b);
287
+ }
288
+ static shl(a, b) {
289
+ return a.shln(b);
290
+ }
291
+ static shr(a, b) {
292
+ return a.shrn(b);
293
+ }
294
+ };
295
+ var MAX_EXPONENTIAL = 524288;
296
+ var I32_MIN = new BN2("-2147483648");
297
+ function mulQ64(left, right) {
298
+ const product = left.mul(right);
299
+ if (product.gt(U128_MAX)) {
300
+ throw new Error(ProgramError.MathOverflow);
301
+ }
302
+ return product.shrn(RESOLUTION);
303
+ }
304
+ function pow(base, exponent, scaling = true) {
305
+ const one = new BN2(1).shln(RESOLUTION);
306
+ if (exponent.eq(I32_MIN) || base.isNeg() || base.gt(U128_MAX)) {
307
+ throw new Error(ProgramError.MathOverflow);
308
+ }
309
+ if (exponent.isZero()) {
310
+ return one;
311
+ }
312
+ let invert = exponent.isNeg();
313
+ const exp = invert ? exponent.neg() : exponent;
314
+ if (exp.gte(new BN2(MAX_EXPONENTIAL))) {
315
+ throw new Error(ProgramError.MathOverflow);
316
+ }
317
+ let squaredBase = base;
318
+ let result = one;
319
+ if (squaredBase.gte(result)) {
320
+ squaredBase = U128_MAX.div(squaredBase);
321
+ invert = !invert;
322
+ }
323
+ let remaining = exp;
324
+ while (!remaining.isZero()) {
325
+ if (remaining.isOdd()) {
326
+ result = mulQ64(result, squaredBase);
327
+ }
328
+ squaredBase = mulQ64(squaredBase, squaredBase);
329
+ remaining = remaining.shrn(1);
330
+ }
331
+ if (result.isZero()) {
332
+ throw new Error(ProgramError.MathOverflow);
333
+ }
334
+ if (invert) {
335
+ result = U128_MAX.div(result);
336
+ }
337
+ return scaling ? result : result.shrn(RESOLUTION);
338
+ }
339
+
340
+ // src/math/utilsMath.ts
341
+ import BN3 from "bn.js";
342
+ function mulDiv(x, y, denominator, rounding) {
343
+ if (denominator.isZero()) {
344
+ throw new Error(ProgramError.MathOverflow);
345
+ }
346
+ const prod = x.mul(y);
347
+ if (rounding === 0 /* Up */) {
348
+ return prod.add(denominator.subn(1)).div(denominator);
349
+ }
350
+ return prod.div(denominator);
351
+ }
352
+ function toNumerator(bps, feeDenominator) {
353
+ return mulDiv(bps, feeDenominator, new BN3(MAX_BASIS_POINT), 1 /* Down */);
354
+ }
355
+ function sqrt(value) {
356
+ if (value.lten(1)) {
357
+ return value;
358
+ }
359
+ let x = value;
360
+ let y = value.addn(1).divn(2);
361
+ while (y.lt(x)) {
362
+ x = y;
363
+ y = x.add(value.div(x)).divn(2);
364
+ }
365
+ return x;
366
+ }
367
+
368
+ // src/math/curve.ts
369
+ import BN4 from "bn.js";
370
+ function requireU64(value) {
371
+ if (value.gt(U64_MAX)) {
372
+ throw new Error(ProgramError.MathOverflow);
373
+ }
374
+ return value;
375
+ }
376
+ function requireU128(value) {
377
+ if (value.gt(U128_MAX)) {
378
+ throw new Error(ProgramError.MathOverflow);
379
+ }
380
+ return value;
381
+ }
382
+ function getInitialLiquidityFromDeltaQuote(quoteAmount, sqrtMinPrice, sqrtPrice) {
383
+ const priceDelta = SafeMath.sub(sqrtPrice, sqrtMinPrice);
384
+ return requireU128(SafeMath.div(SafeMath.shl(quoteAmount, 128), priceDelta));
385
+ }
386
+ function getInitialLiquidityFromDeltaBase(baseAmount, sqrtMaxPrice, sqrtPrice) {
387
+ const priceDelta = SafeMath.sub(sqrtMaxPrice, sqrtPrice);
388
+ const prod = SafeMath.mul(SafeMath.mul(baseAmount, sqrtPrice), sqrtMaxPrice);
389
+ return SafeMath.div(prod, priceDelta);
390
+ }
391
+ function getDeltaAmountBaseUnsigned(lowerSqrtPrice, upperSqrtPrice, liquidity, round) {
392
+ return requireU64(
393
+ getDeltaAmountBaseUnsigned256(
394
+ lowerSqrtPrice,
395
+ upperSqrtPrice,
396
+ liquidity,
397
+ round
398
+ )
399
+ );
400
+ }
401
+ function getDeltaAmountBaseUnsigned256(lowerSqrtPrice, upperSqrtPrice, liquidity, round) {
402
+ const numerator = SafeMath.sub(upperSqrtPrice, lowerSqrtPrice);
403
+ const denominator = SafeMath.mul(lowerSqrtPrice, upperSqrtPrice);
404
+ return mulDiv(liquidity, numerator, denominator, round);
405
+ }
406
+ function getDeltaAmountQuoteUnsigned(lowerSqrtPrice, upperSqrtPrice, liquidity, round) {
407
+ return requireU64(
408
+ getDeltaAmountQuoteUnsigned256(
409
+ lowerSqrtPrice,
410
+ upperSqrtPrice,
411
+ liquidity,
412
+ round
413
+ )
414
+ );
415
+ }
416
+ function getDeltaAmountQuoteUnsigned256(lowerSqrtPrice, upperSqrtPrice, liquidity, round) {
417
+ const prod = SafeMath.mul(
418
+ liquidity,
419
+ SafeMath.sub(upperSqrtPrice, lowerSqrtPrice)
420
+ );
421
+ if (round === 0 /* Up */) {
422
+ const denominator = new BN4(1).shln(RESOLUTION * 2);
423
+ return SafeMath.div(
424
+ SafeMath.add(prod, denominator.subn(1)),
425
+ denominator
426
+ );
427
+ }
428
+ return SafeMath.shr(prod, RESOLUTION * 2);
429
+ }
430
+ function requireSwapInputs(sqrtPrice, liquidity, amount) {
431
+ requireU128(sqrtPrice);
432
+ requireU128(liquidity);
433
+ requireU64(amount);
434
+ if (sqrtPrice.isZero()) {
435
+ throw new Error("sqrt_price must be greater than 0");
436
+ }
437
+ if (liquidity.isZero()) {
438
+ throw new Error("liquidity must be greater than 0");
439
+ }
440
+ }
441
+ function getNextSqrtPriceFromInput(sqrtPrice, liquidity, amountIn, baseForQuote) {
442
+ requireSwapInputs(sqrtPrice, liquidity, amountIn);
443
+ return baseForQuote ? getNextSqrtPriceFromBaseAmountInRoundingUp(
444
+ sqrtPrice,
445
+ liquidity,
446
+ amountIn
447
+ ) : getNextSqrtPriceFromQuoteAmountInRoundingDown(
448
+ sqrtPrice,
449
+ liquidity,
450
+ amountIn
451
+ );
452
+ }
453
+ function getNextSqrtPriceFromOutput(sqrtPrice, liquidity, amountOut, baseForQuote) {
454
+ requireSwapInputs(sqrtPrice, liquidity, amountOut);
455
+ return baseForQuote ? getNextSqrtPriceFromQuoteAmountOutRoundingDown(
456
+ sqrtPrice,
457
+ liquidity,
458
+ amountOut
459
+ ) : getNextSqrtPriceFromBaseAmountOutRoundingUp(
460
+ sqrtPrice,
461
+ liquidity,
462
+ amountOut
463
+ );
464
+ }
465
+ function getNextSqrtPriceFromQuoteAmountOutRoundingDown(sqrtPrice, liquidity, amount) {
466
+ const qAmount = SafeMath.shl(amount, 128);
467
+ const quotient = SafeMath.div(
468
+ SafeMath.add(qAmount, SafeMath.sub(liquidity, new BN4(1))),
469
+ liquidity
470
+ );
471
+ return requireU128(SafeMath.sub(sqrtPrice, quotient));
472
+ }
473
+ function getNextSqrtPriceFromBaseAmountOutRoundingUp(sqrtPrice, liquidity, amount) {
474
+ if (amount.isZero()) {
475
+ return sqrtPrice;
476
+ }
477
+ const denominator = SafeMath.sub(liquidity, SafeMath.mul(amount, sqrtPrice));
478
+ if (denominator.isZero()) {
479
+ throw new Error(ProgramError.TypeCastFailed);
480
+ }
481
+ return requireU128(mulDiv(liquidity, sqrtPrice, denominator, 0 /* Up */));
482
+ }
483
+ function getNextSqrtPriceFromBaseAmountInRoundingUp(sqrtPrice, liquidity, amount) {
484
+ if (amount.isZero()) {
485
+ return sqrtPrice;
486
+ }
487
+ const denominator = SafeMath.add(liquidity, SafeMath.mul(amount, sqrtPrice));
488
+ return requireU128(mulDiv(liquidity, sqrtPrice, denominator, 0 /* Up */));
489
+ }
490
+ function getNextSqrtPriceFromQuoteAmountInRoundingDown(sqrtPrice, liquidity, amount) {
491
+ const quotient = SafeMath.div(
492
+ SafeMath.shl(amount, RESOLUTION * 2),
493
+ liquidity
494
+ );
495
+ return requireU128(SafeMath.add(sqrtPrice, quotient));
496
+ }
497
+ function liveCurve(curve) {
498
+ const end = curve.findIndex(
499
+ (point) => point.sqrtPrice.isZero() || point.liquidity.isZero()
500
+ );
501
+ return end === -1 ? curve : curve.slice(0, end);
502
+ }
503
+
504
+ // src/math/transferFee.ts
505
+ import {
506
+ calculateFee,
507
+ getEpochFee,
508
+ getTransferFeeConfig,
509
+ MAX_FEE_BASIS_POINTS
510
+ } from "@solana/spl-token";
511
+ import BN5 from "bn.js";
512
+ var ZERO = new BN5(0);
513
+ function toSplTransferFee(transferFee) {
514
+ return {
515
+ epoch: BigInt(0),
516
+ maximumFee: BigInt(transferFee.maximumFee.toString()),
517
+ transferFeeBasisPoints: transferFee.transferFeeBasisPoints
518
+ };
519
+ }
520
+ function isZeroTransferFee(transferFee) {
521
+ if (!transferFee || transferFee.transferFeeBasisPoints === 0) {
522
+ return true;
523
+ }
524
+ const maximumFee = transferFee.maximumFee;
525
+ return typeof maximumFee === "bigint" ? maximumFee === BigInt(0) : maximumFee.isZero();
526
+ }
527
+ function getBaseTransferFee(transferFeeBasisPoints) {
528
+ if (!transferFeeBasisPoints) {
529
+ return null;
530
+ }
531
+ return {
532
+ transferFeeBasisPoints,
533
+ maximumFee: U64_MAX
534
+ };
535
+ }
536
+ function getConfigBaseTransferFee(config) {
537
+ if (config.transferFeeFlag !== 1) {
538
+ return null;
539
+ }
540
+ return {
541
+ transferFeeBasisPoints: config.transferFeeBasisPoints,
542
+ maximumFee: U64_MAX
543
+ };
544
+ }
545
+ function getEpochTransferFee(mint, currentEpoch) {
546
+ const transferFeeConfig = getTransferFeeConfig(mint);
547
+ if (!transferFeeConfig) {
548
+ return null;
549
+ }
550
+ const epochFee = getEpochFee(transferFeeConfig, BigInt(currentEpoch));
551
+ return {
552
+ transferFeeBasisPoints: epochFee.transferFeeBasisPoints,
553
+ maximumFee: new BN5(epochFee.maximumFee.toString())
554
+ };
555
+ }
556
+ function resolveSwapTransferFees(config, swapBaseForQuote, transferFees) {
557
+ let base;
558
+ if (transferFees?.baseMint) {
559
+ if (transferFees.currentEpoch === void 0) {
560
+ throw new Error("currentEpoch is required to quote a transfer fee");
561
+ }
562
+ base = getEpochTransferFee(
563
+ transferFees.baseMint,
564
+ transferFees.currentEpoch
565
+ );
566
+ } else if (transferFees?.baseTransferFeeBasisPoints !== void 0) {
567
+ base = getBaseTransferFee(transferFees.baseTransferFeeBasisPoints);
568
+ } else {
569
+ base = getConfigBaseTransferFee(config);
570
+ }
571
+ let quote = null;
572
+ if (transferFees?.quoteMint) {
573
+ if (config.quoteMint && !transferFees.quoteMint.address.equals(config.quoteMint)) {
574
+ throw new Error("quoteMint does not match config.quoteMint");
575
+ }
576
+ if (transferFees.currentEpoch === void 0) {
577
+ throw new Error("currentEpoch is required to quote a transfer fee");
578
+ }
579
+ quote = getEpochTransferFee(
580
+ transferFees.quoteMint,
581
+ transferFees.currentEpoch
582
+ );
583
+ } else if (config.quoteTokenFlag === 1 /* Token2022 */) {
584
+ throw new Error(
585
+ "quoteMint and currentEpoch are required for a Token-2022 quote mint, use getSwapQuoteTransferFees"
586
+ );
587
+ }
588
+ return swapBaseForQuote ? { input: base, output: quote } : { input: quote, output: base };
589
+ }
590
+ function calculateTransferFeeExcludedAmount(transferFee, includedAmount) {
591
+ if (!transferFee || isZeroTransferFee(transferFee) || includedAmount.isZero()) {
592
+ return { amount: includedAmount, transferFee: ZERO };
593
+ }
594
+ const fee = new BN5(
595
+ calculateFee(
596
+ toSplTransferFee(transferFee),
597
+ BigInt(includedAmount.toString())
598
+ ).toString()
599
+ );
600
+ return {
601
+ amount: includedAmount.sub(fee),
602
+ transferFee: fee
603
+ };
604
+ }
605
+ function calculatePreFeeAmount(transferFee, excludedAmount) {
606
+ if (excludedAmount.isZero() || isZeroTransferFee(transferFee)) {
607
+ return excludedAmount;
608
+ }
609
+ if (transferFee.transferFeeBasisPoints === MAX_FEE_BASIS_POINTS) {
610
+ return excludedAmount.add(transferFee.maximumFee);
611
+ }
612
+ const oneInBasisPoints = new BN5(MAX_FEE_BASIS_POINTS);
613
+ const denominator = oneInBasisPoints.subn(
614
+ transferFee.transferFeeBasisPoints
615
+ );
616
+ const rawPreFeeAmount = excludedAmount.mul(oneInBasisPoints).add(denominator).subn(1).div(denominator);
617
+ if (rawPreFeeAmount.sub(excludedAmount).gte(transferFee.maximumFee)) {
618
+ return excludedAmount.add(transferFee.maximumFee);
619
+ }
620
+ return rawPreFeeAmount;
621
+ }
622
+ function calculateTransferFeeIncludedAmount(transferFee, excludedAmount) {
623
+ if (excludedAmount.isZero()) {
624
+ return { amount: ZERO, transferFee: ZERO };
625
+ }
626
+ if (!transferFee || isZeroTransferFee(transferFee)) {
627
+ return { amount: excludedAmount, transferFee: ZERO };
628
+ }
629
+ const preFeeAmount = calculatePreFeeAmount(transferFee, excludedAmount);
630
+ if (preFeeAmount.gt(U64_MAX)) {
631
+ throw new Error(ProgramError.MathOverflow);
632
+ }
633
+ const fee = calculateTransferFeeExcludedAmount(
634
+ transferFee,
635
+ preFeeAmount
636
+ ).transferFee;
637
+ const includedAmount = excludedAmount.add(fee);
638
+ const verification = calculateTransferFeeExcludedAmount(
639
+ transferFee,
640
+ includedAmount
641
+ ).transferFee;
642
+ if (!fee.eq(verification)) {
643
+ throw new Error(ProgramError.FeeInverseIsIncorrect);
644
+ }
645
+ return { amount: includedAmount, transferFee: fee };
646
+ }
647
+
648
+ // src/math/poolFees/feeScheduler.ts
649
+ import BN6 from "bn.js";
650
+ function getFeeSchedulerMinBaseFeeNumerator(cliffFeeNumerator, numberOfPeriod, reductionFactor, feeSchedulerMode) {
651
+ return getBaseFeeNumeratorByPeriod(
652
+ cliffFeeNumerator,
653
+ numberOfPeriod,
654
+ new BN6(numberOfPeriod),
655
+ reductionFactor,
656
+ feeSchedulerMode
657
+ );
658
+ }
659
+ function getBaseFeeNumeratorByPeriod(cliffFeeNumerator, numberOfPeriod, period, reductionFactor, feeSchedulerMode) {
660
+ const periodNumber = BN6.min(period, new BN6(numberOfPeriod)).toNumber();
661
+ if (periodNumber > U16_MAX) {
662
+ throw new Error(ProgramError.MathOverflow);
663
+ }
664
+ switch (feeSchedulerMode) {
665
+ case 0 /* FeeSchedulerLinear */:
666
+ return getFeeNumeratorOnLinearFeeScheduler(
667
+ cliffFeeNumerator,
668
+ reductionFactor,
669
+ periodNumber
670
+ );
671
+ case 1 /* FeeSchedulerExponential */:
672
+ return getFeeNumeratorOnExponentialFeeScheduler(
673
+ cliffFeeNumerator,
674
+ reductionFactor,
675
+ periodNumber
676
+ );
677
+ default:
678
+ throw new Error(ProgramError.InvalidBaseFeeMode);
679
+ }
680
+ }
681
+ function getFeeNumeratorOnLinearFeeScheduler(cliffFeeNumerator, reductionFactor, period) {
682
+ return SafeMath.sub(
683
+ cliffFeeNumerator,
684
+ SafeMath.mul(new BN6(period), reductionFactor)
685
+ );
686
+ }
687
+ function getFeeNumeratorOnExponentialFeeScheduler(cliffFeeNumerator, reductionFactor, period) {
688
+ if (period === 0) {
689
+ return cliffFeeNumerator;
690
+ }
691
+ const bps = SafeMath.div(
692
+ SafeMath.shl(reductionFactor, 64),
693
+ new BN6(MAX_BASIS_POINT)
694
+ );
695
+ const base = SafeMath.sub(ONE_Q64, bps);
696
+ const result = pow(base, new BN6(period));
697
+ return SafeMath.div(SafeMath.mul(cliffFeeNumerator, result), ONE_Q64);
698
+ }
699
+ function getBaseFeeNumerator(cliffFeeNumerator, numberOfPeriod, periodFrequency, reductionFactor, feeSchedulerMode, currentPoint, activationPoint) {
700
+ if (periodFrequency.isZero()) {
701
+ return cliffFeeNumerator;
702
+ }
703
+ const period = SafeMath.div(
704
+ SafeMath.sub(currentPoint, activationPoint),
705
+ periodFrequency
706
+ );
707
+ return getBaseFeeNumeratorByPeriod(
708
+ cliffFeeNumerator,
709
+ numberOfPeriod,
710
+ period,
711
+ reductionFactor,
712
+ feeSchedulerMode
713
+ );
714
+ }
715
+
716
+ // src/math/feeAmount.ts
717
+ import BN7 from "bn.js";
718
+ function getExcludedFeeAmount(tradeFeeNumerator2, includedFeeAmount) {
719
+ const tradingFee = mulDiv(
720
+ includedFeeAmount,
721
+ tradeFeeNumerator2,
722
+ new BN7(FEE_DENOMINATOR),
723
+ 0 /* Up */
724
+ );
725
+ return [SafeMath.sub(includedFeeAmount, tradingFee), tradingFee];
726
+ }
727
+ function getIncludedFeeAmount(tradeFeeNumerator2, excludedFeeAmount) {
728
+ const includedFeeAmount = mulDiv(
729
+ excludedFeeAmount,
730
+ new BN7(FEE_DENOMINATOR),
731
+ SafeMath.sub(new BN7(FEE_DENOMINATOR), tradeFeeNumerator2),
732
+ 0 /* Up */
733
+ );
734
+ if (includedFeeAmount.gt(U64_MAX)) {
735
+ throw new Error(ProgramError.TypeCastFailed);
736
+ }
737
+ return [
738
+ includedFeeAmount,
739
+ SafeMath.sub(includedFeeAmount, excludedFeeAmount)
740
+ ];
741
+ }
742
+
743
+ // src/math/poolFees/rateLimiter.ts
744
+ import BN8 from "bn.js";
745
+ function isRateLimiterApplied(currentPoint, activationPoint, tradeDirection, maxLimiterDuration, referenceAmount, feeIncrementBps) {
746
+ if (isZeroRateLimiter(referenceAmount, maxLimiterDuration, feeIncrementBps)) {
747
+ return false;
748
+ }
749
+ if (tradeDirection === 0 /* BaseToQuote */) {
750
+ return false;
751
+ }
752
+ return currentPoint.lte(activationPoint.add(maxLimiterDuration));
753
+ }
754
+ function isZeroRateLimiter(referenceAmount, maxLimiterDuration, feeIncrementBps) {
755
+ return referenceAmount.isZero() && maxLimiterDuration.isZero() && feeIncrementBps.isZero();
756
+ }
757
+ function isNonZeroRateLimiter(referenceAmount, maxLimiterDuration, feeIncrementBps) {
758
+ return !referenceAmount.isZero() && !maxLimiterDuration.isZero() && !feeIncrementBps.isZero();
759
+ }
760
+ function getMaxIndex(cliffFeeNumerator, feeIncrementBps) {
761
+ const deltaNumerator = SafeMath.sub(
762
+ new BN8(MAX_FEE_NUMERATOR),
763
+ cliffFeeNumerator
764
+ );
765
+ return SafeMath.div(
766
+ deltaNumerator,
767
+ toNumerator(feeIncrementBps, new BN8(FEE_DENOMINATOR))
768
+ );
769
+ }
770
+ function getCheckedAmounts(cliffFeeNumerator, referenceAmount, feeIncrementBps) {
771
+ const maxIndex = getMaxIndex(cliffFeeNumerator, feeIncrementBps);
772
+ const maxIndexInputAmount = maxIndex.addn(1).mul(referenceAmount);
773
+ const isOverflow = maxIndexInputAmount.gt(U64_MAX);
774
+ const checkedIncludedFeeAmount = isOverflow ? U64_MAX : maxIndexInputAmount;
775
+ const checkedExcludedFeeAmount = getRateLimiterExcludedFeeAmount(
776
+ cliffFeeNumerator,
777
+ referenceAmount,
778
+ feeIncrementBps,
779
+ checkedIncludedFeeAmount
780
+ );
781
+ return [checkedExcludedFeeAmount, checkedIncludedFeeAmount, isOverflow];
782
+ }
783
+ function getFeeNumeratorFromExcludedAmount(cliffFeeNumerator, referenceAmount, feeIncrementBps, excludedFeeAmount) {
784
+ const excludedFeeReferenceAmount = getRateLimiterExcludedFeeAmount(
785
+ cliffFeeNumerator,
786
+ referenceAmount,
787
+ feeIncrementBps,
788
+ referenceAmount
789
+ );
790
+ if (excludedFeeAmount.lte(excludedFeeReferenceAmount)) {
791
+ return cliffFeeNumerator;
792
+ }
793
+ const [checkedExcludedFeeAmount, checkedIncludedFeeAmount, isOverflow] = getCheckedAmounts(cliffFeeNumerator, referenceAmount, feeIncrementBps);
794
+ if (excludedFeeAmount.eq(checkedExcludedFeeAmount)) {
795
+ return getFeeNumeratorFromIncludedAmount(
796
+ cliffFeeNumerator,
797
+ referenceAmount,
798
+ feeIncrementBps,
799
+ checkedIncludedFeeAmount
800
+ );
801
+ }
802
+ let includedFeeAmount;
803
+ if (excludedFeeAmount.lt(checkedExcludedFeeAmount)) {
804
+ const two = new BN8(2);
805
+ const i = toNumerator(feeIncrementBps, new BN8(FEE_DENOMINATOR));
806
+ const x0 = referenceAmount;
807
+ const d = new BN8(FEE_DENOMINATOR);
808
+ const c = cliffFeeNumerator;
809
+ const y = two.mul(d).mul(x0).add(i.mul(x0)).sub(two.mul(c).mul(x0));
810
+ const z = two.mul(excludedFeeAmount).mul(d).mul(x0);
811
+ const discriminant = y.mul(y).sub(new BN8(4).mul(i).mul(z));
812
+ const wholePeriodsInput = y.sub(sqrt(discriminant)).div(two.mul(i));
813
+ const aPlusOne = wholePeriodsInput.div(x0);
814
+ const excludedFeeRemainingAmount = SafeMath.sub(
815
+ excludedFeeAmount,
816
+ getRateLimiterExcludedFeeAmount(
817
+ cliffFeeNumerator,
818
+ referenceAmount,
819
+ feeIncrementBps,
820
+ wholePeriodsInput
821
+ )
822
+ );
823
+ const [includedFeeRemainingAmount] = getIncludedFeeAmount(
824
+ c.add(i.mul(aPlusOne)),
825
+ excludedFeeRemainingAmount
826
+ );
827
+ includedFeeAmount = wholePeriodsInput.add(includedFeeRemainingAmount);
828
+ } else {
829
+ if (isOverflow) {
830
+ throw new Error(ProgramError.MathOverflow);
831
+ }
832
+ const excludedFeeRemainingAmount = SafeMath.sub(
833
+ excludedFeeAmount,
834
+ checkedExcludedFeeAmount
835
+ );
836
+ const [includedFeeRemainingAmount] = getIncludedFeeAmount(
837
+ new BN8(MAX_FEE_NUMERATOR),
838
+ excludedFeeRemainingAmount
839
+ );
840
+ includedFeeAmount = checkedIncludedFeeAmount.add(
841
+ includedFeeRemainingAmount
842
+ );
843
+ }
844
+ const tradingFee = SafeMath.sub(includedFeeAmount, excludedFeeAmount);
845
+ const feeNumerator = mulDiv(
846
+ tradingFee,
847
+ new BN8(FEE_DENOMINATOR),
848
+ includedFeeAmount,
849
+ 0 /* Up */
850
+ );
851
+ if (feeNumerator.lt(cliffFeeNumerator)) {
852
+ throw new Error(ProgramError.UndeterminedError);
853
+ }
854
+ return feeNumerator;
855
+ }
856
+ function getRateLimiterExcludedFeeAmount(cliffFeeNumerator, referenceAmount, feeIncrementBps, includedFeeAmount) {
857
+ const feeNumerator = getFeeNumeratorFromIncludedAmount(
858
+ cliffFeeNumerator,
859
+ referenceAmount,
860
+ feeIncrementBps,
861
+ includedFeeAmount
862
+ );
863
+ return getExcludedFeeAmount(feeNumerator, includedFeeAmount)[0];
864
+ }
865
+ function getMaxOutAmountWithMinBaseFee(cliffFeeNumerator, referenceAmount, feeIncrementBps) {
866
+ return getRateLimiterExcludedFeeAmount(
867
+ cliffFeeNumerator,
868
+ referenceAmount,
869
+ feeIncrementBps,
870
+ referenceAmount
871
+ );
872
+ }
873
+ function getFeeNumeratorFromIncludedAmount(cliffFeeNumerator, referenceAmount, feeIncrementBps, includedFeeAmount) {
874
+ if (includedFeeAmount.lte(referenceAmount)) {
875
+ return cliffFeeNumerator;
876
+ }
877
+ const c = cliffFeeNumerator;
878
+ const diff = includedFeeAmount.sub(referenceAmount);
879
+ const a = diff.div(referenceAmount);
880
+ const b = diff.mod(referenceAmount);
881
+ const maxIndex = getMaxIndex(cliffFeeNumerator, feeIncrementBps);
882
+ const i = toNumerator(feeIncrementBps, new BN8(FEE_DENOMINATOR));
883
+ const x0 = referenceAmount;
884
+ const one = new BN8(1);
885
+ const two = new BN8(2);
886
+ let tradingFeeNumerator;
887
+ if (a.lt(maxIndex)) {
888
+ const numerator1 = c.add(c.mul(a)).add(i.mul(a).mul(a.add(one)).div(two));
889
+ const numerator2 = c.add(i.mul(a.add(one)));
890
+ tradingFeeNumerator = x0.mul(numerator1).add(b.mul(numerator2));
891
+ } else {
892
+ const numerator1 = c.add(c.mul(maxIndex)).add(i.mul(maxIndex).mul(maxIndex.add(one)).div(two));
893
+ const leftAmount = a.sub(maxIndex).mul(x0).add(b);
894
+ tradingFeeNumerator = x0.mul(numerator1).add(leftAmount.mul(new BN8(MAX_FEE_NUMERATOR)));
895
+ }
896
+ const denominator = new BN8(FEE_DENOMINATOR);
897
+ const tradingFee = tradingFeeNumerator.add(denominator).sub(one).div(denominator);
898
+ return mulDiv(
899
+ tradingFee,
900
+ new BN8(FEE_DENOMINATOR),
901
+ includedFeeAmount,
902
+ 0 /* Up */
903
+ );
904
+ }
905
+
906
+ // src/math/poolFees/baseFee.ts
907
+ import BN9 from "bn.js";
908
+ var FeeRateLimiter = class {
909
+ constructor(cliffFeeNumerator, feeIncrementBps, maxLimiterDuration, referenceAmount) {
910
+ this.cliffFeeNumerator = cliffFeeNumerator;
911
+ this.feeIncrementBps = feeIncrementBps;
912
+ this.maxLimiterDuration = maxLimiterDuration;
913
+ this.referenceAmount = referenceAmount;
914
+ }
915
+ getMinBaseFeeNumerator() {
916
+ return this.cliffFeeNumerator;
917
+ }
918
+ isApplied(currentPoint, activationPoint, tradeDirection) {
919
+ return isRateLimiterApplied(
920
+ currentPoint,
921
+ activationPoint,
922
+ tradeDirection,
923
+ this.maxLimiterDuration,
924
+ this.referenceAmount,
925
+ new BN9(this.feeIncrementBps)
926
+ );
927
+ }
928
+ getBaseFeeNumeratorFromIncludedFeeAmount(currentPoint, activationPoint, tradeDirection, includedFeeAmount) {
929
+ if (!this.isApplied(currentPoint, activationPoint, tradeDirection)) {
930
+ return this.cliffFeeNumerator;
931
+ }
932
+ return getFeeNumeratorFromIncludedAmount(
933
+ this.cliffFeeNumerator,
934
+ this.referenceAmount,
935
+ new BN9(this.feeIncrementBps),
936
+ includedFeeAmount
937
+ );
938
+ }
939
+ getBaseFeeNumeratorFromExcludedFeeAmount(currentPoint, activationPoint, tradeDirection, excludedFeeAmount) {
940
+ if (!this.isApplied(currentPoint, activationPoint, tradeDirection)) {
941
+ return this.cliffFeeNumerator;
942
+ }
943
+ return getFeeNumeratorFromExcludedAmount(
944
+ this.cliffFeeNumerator,
945
+ this.referenceAmount,
946
+ new BN9(this.feeIncrementBps),
947
+ excludedFeeAmount
948
+ );
949
+ }
950
+ };
951
+ var FeeScheduler = class {
952
+ constructor(cliffFeeNumerator, numberOfPeriod, periodFrequency, reductionFactor, feeSchedulerMode) {
953
+ this.cliffFeeNumerator = cliffFeeNumerator;
954
+ this.numberOfPeriod = numberOfPeriod;
955
+ this.periodFrequency = periodFrequency;
956
+ this.reductionFactor = reductionFactor;
957
+ this.feeSchedulerMode = feeSchedulerMode;
958
+ }
959
+ getMinBaseFeeNumerator() {
960
+ return getFeeSchedulerMinBaseFeeNumerator(
961
+ this.cliffFeeNumerator,
962
+ this.numberOfPeriod,
963
+ this.reductionFactor,
964
+ this.feeSchedulerMode
965
+ );
966
+ }
967
+ // a scheduler's fee depends on the point, not on the amount
968
+ getBaseFeeNumeratorFromIncludedFeeAmount(currentPoint, activationPoint) {
969
+ return getBaseFeeNumerator(
970
+ this.cliffFeeNumerator,
971
+ this.numberOfPeriod,
972
+ this.periodFrequency,
973
+ this.reductionFactor,
974
+ this.feeSchedulerMode,
975
+ currentPoint,
976
+ activationPoint
977
+ );
978
+ }
979
+ getBaseFeeNumeratorFromExcludedFeeAmount(currentPoint, activationPoint) {
980
+ return this.getBaseFeeNumeratorFromIncludedFeeAmount(
981
+ currentPoint,
982
+ activationPoint
983
+ );
984
+ }
985
+ };
986
+ function getBaseFeeHandler(cliffFeeNumerator, firstFactor, secondFactor, thirdFactor, baseFeeMode) {
987
+ switch (baseFeeMode) {
988
+ case 0 /* FeeSchedulerLinear */:
989
+ case 1 /* FeeSchedulerExponential */:
990
+ return new FeeScheduler(
991
+ cliffFeeNumerator,
992
+ firstFactor,
993
+ secondFactor,
994
+ thirdFactor,
995
+ baseFeeMode
996
+ );
997
+ case 2 /* RateLimiter */:
998
+ return new FeeRateLimiter(
999
+ cliffFeeNumerator,
1000
+ firstFactor,
1001
+ secondFactor,
1002
+ thirdFactor
1003
+ );
1004
+ default:
1005
+ throw new Error(ProgramError.InvalidBaseFeeMode);
1006
+ }
1007
+ }
1008
+
1009
+ // src/math/poolFees/dynamicFee.ts
1010
+ import BN10 from "bn.js";
1011
+ function isDynamicFeeEnabled(dynamicFee) {
1012
+ return dynamicFee.initialized !== 0;
1013
+ }
1014
+ function getVariableFeeNumerator(dynamicFee, volatilityTracker) {
1015
+ if (!isDynamicFeeEnabled(dynamicFee)) {
1016
+ return new BN10(0);
1017
+ }
1018
+ const volatilityTimesBinStep = SafeMath.mul(
1019
+ volatilityTracker.volatilityAccumulator,
1020
+ new BN10(dynamicFee.binStep)
1021
+ );
1022
+ const vFee = SafeMath.mul(
1023
+ SafeMath.mul(volatilityTimesBinStep, volatilityTimesBinStep),
1024
+ new BN10(dynamicFee.variableFeeControl)
1025
+ );
1026
+ return SafeMath.div(
1027
+ SafeMath.add(vFee, DYNAMIC_FEE_ROUNDING_OFFSET),
1028
+ DYNAMIC_FEE_SCALING_FACTOR
1029
+ );
1030
+ }
1031
+
1032
+ // src/math/feeMath.ts
1033
+ import BN11 from "bn.js";
1034
+ var FEE_MODES = {
1035
+ [0 /* QuoteToken */]: {
1036
+ [0 /* BaseToQuote */]: [false, false],
1037
+ [1 /* QuoteToBase */]: [true, false]
1038
+ },
1039
+ [1 /* OutputToken */]: {
1040
+ [0 /* BaseToQuote */]: [false, false],
1041
+ [1 /* QuoteToBase */]: [false, true]
1042
+ }
1043
+ };
1044
+ function getFeeMode(collectFeeMode, tradeDirection, hasReferral) {
1045
+ const mode = FEE_MODES[collectFeeMode]?.[tradeDirection];
1046
+ if (!mode) {
1047
+ throw new Error(ProgramError.InvalidCollectFeeMode);
1048
+ }
1049
+ const [feesOnInput, feesOnBaseToken] = mode;
1050
+ return { feesOnInput, feesOnBaseToken, hasReferral };
1051
+ }
1052
+ function baseFeeHandlerOf(poolFees) {
1053
+ const { baseFee } = poolFees;
1054
+ return getBaseFeeHandler(
1055
+ baseFee.cliffFeeNumerator,
1056
+ baseFee.firstFactor,
1057
+ baseFee.secondFactor,
1058
+ baseFee.thirdFactor,
1059
+ baseFee.baseFeeMode
1060
+ );
1061
+ }
1062
+ function getTotalFeeNumeratorFromIncludedFeeAmount(poolFees, volatilityTracker, currentPoint, activationPoint, includedFeeAmount, tradeDirection) {
1063
+ const baseFeeNumerator = baseFeeHandlerOf(
1064
+ poolFees
1065
+ ).getBaseFeeNumeratorFromIncludedFeeAmount(
1066
+ currentPoint,
1067
+ activationPoint,
1068
+ tradeDirection,
1069
+ includedFeeAmount
1070
+ );
1071
+ return getTotalFeeNumerator(
1072
+ baseFeeNumerator,
1073
+ poolFees.dynamicFee,
1074
+ volatilityTracker
1075
+ );
1076
+ }
1077
+ function getTotalFeeNumeratorFromExcludedFeeAmount(poolFees, volatilityTracker, currentPoint, activationPoint, excludedFeeAmount, tradeDirection) {
1078
+ const baseFeeNumerator = baseFeeHandlerOf(
1079
+ poolFees
1080
+ ).getBaseFeeNumeratorFromExcludedFeeAmount(
1081
+ currentPoint,
1082
+ activationPoint,
1083
+ tradeDirection,
1084
+ excludedFeeAmount
1085
+ );
1086
+ return getTotalFeeNumerator(
1087
+ baseFeeNumerator,
1088
+ poolFees.dynamicFee,
1089
+ volatilityTracker
1090
+ );
1091
+ }
1092
+ function getTotalFeeNumerator(baseFeeNumerator, dynamicFee, volatilityTracker) {
1093
+ return BN11.min(
1094
+ SafeMath.add(
1095
+ getVariableFeeNumerator(dynamicFee, volatilityTracker),
1096
+ baseFeeNumerator
1097
+ ),
1098
+ new BN11(MAX_FEE_NUMERATOR)
1099
+ );
1100
+ }
1101
+ function getFeeOnAmount(tradeFeeNumerator2, amount, hasReferral) {
1102
+ const [amountAfterFee, feeAmount] = getExcludedFeeAmount(
1103
+ tradeFeeNumerator2,
1104
+ amount
1105
+ );
1106
+ const [tradingFee, protocolFee, referralFee] = splitFees(
1107
+ feeAmount,
1108
+ hasReferral
1109
+ );
1110
+ return { amount: amountAfterFee, tradingFee, protocolFee, referralFee };
1111
+ }
1112
+ function splitFees(feeAmount, hasReferral) {
1113
+ const protocolFee = mulDiv(
1114
+ feeAmount,
1115
+ new BN11(PROTOCOL_FEE_PERCENT),
1116
+ new BN11(100),
1117
+ 1 /* Down */
1118
+ );
1119
+ const tradingFee = SafeMath.sub(feeAmount, protocolFee);
1120
+ const referralFee = hasReferral ? mulDiv(
1121
+ protocolFee,
1122
+ new BN11(HOST_FEE_PERCENT),
1123
+ new BN11(100),
1124
+ 1 /* Down */
1125
+ ) : new BN11(0);
1126
+ return [tradingFee, SafeMath.sub(protocolFee, referralFee), referralFee];
1127
+ }
1128
+
1129
+ // src/math/swapQuote.ts
1130
+ import BN12 from "bn.js";
1131
+ var ZERO2 = new BN12(0);
1132
+ var NO_FEES = {
1133
+ tradingFee: ZERO2,
1134
+ protocolFee: ZERO2,
1135
+ referralFee: ZERO2
1136
+ };
1137
+ function addU64(total, amount) {
1138
+ const sum = total.add(amount);
1139
+ if (sum.gt(U64_MAX)) {
1140
+ throw new Error(ProgramError.MathOverflow);
1141
+ }
1142
+ return sum;
1143
+ }
1144
+ function u64(amount) {
1145
+ if (amount.gt(U64_MAX)) {
1146
+ throw new Error(ProgramError.MathOverflow);
1147
+ }
1148
+ return amount;
1149
+ }
1150
+ function assertSlippageBps(slippageBps) {
1151
+ if (slippageBps < 0 || slippageBps > MAX_BASIS_POINT) {
1152
+ throw new Error(`slippageBps must be between 0 and ${MAX_BASIS_POINT}`);
1153
+ }
1154
+ }
1155
+ function minimumAmountOutWithSlippage(amount, slippageBps) {
1156
+ assertSlippageBps(slippageBps);
1157
+ return amount.muln(MAX_BASIS_POINT - slippageBps).divn(MAX_BASIS_POINT);
1158
+ }
1159
+ function maximumAmountInWithSlippage(amount, slippageBps) {
1160
+ assertSlippageBps(slippageBps);
1161
+ return amount.muln(MAX_BASIS_POINT + slippageBps).divn(MAX_BASIS_POINT);
1162
+ }
1163
+ function isFirstSwapWithMinFee(virtualPool, config, hasReferral, eligibleForFirstSwapWithMinFee) {
1164
+ return eligibleForFirstSwapWithMinFee && !hasReferral && config.enableFirstSwapWithMinFee === 1 && virtualPool.poolState.hasSwap === 0;
1165
+ }
1166
+ function beginSwapQuote(virtualPool, config, swapBaseForQuote, amount, hasReferral, transferFees) {
1167
+ if (amount.isZero()) {
1168
+ throw new Error(ProgramError.AmountIsZero);
1169
+ }
1170
+ if (virtualPool.poolState.quoteReserve.gte(config.migrationQuoteThreshold)) {
1171
+ throw new Error(ProgramError.PoolIsCompleted);
1172
+ }
1173
+ const tradeDirection = swapBaseForQuote ? 0 /* BaseToQuote */ : 1 /* QuoteToBase */;
1174
+ return {
1175
+ tradeDirection,
1176
+ feeMode: getFeeMode(config.collectFeeMode, tradeDirection, hasReferral),
1177
+ ...resolveSwapTransferFees(config, swapBaseForQuote, transferFees)
1178
+ };
1179
+ }
1180
+ function tradeFeeNumerator(virtualPool, config, currentPoint, tradeDirection, amount, amountExcludesFee, eligibleForFirstSwapWithMinFee) {
1181
+ if (eligibleForFirstSwapWithMinFee) {
1182
+ const { baseFee } = config.poolFees;
1183
+ return getBaseFeeHandler(
1184
+ baseFee.cliffFeeNumerator,
1185
+ baseFee.firstFactor,
1186
+ baseFee.secondFactor,
1187
+ baseFee.thirdFactor,
1188
+ baseFee.baseFeeMode
1189
+ ).getMinBaseFeeNumerator();
1190
+ }
1191
+ const totalFeeNumerator = amountExcludesFee ? getTotalFeeNumeratorFromExcludedFeeAmount : getTotalFeeNumeratorFromIncludedFeeAmount;
1192
+ return totalFeeNumerator(
1193
+ config.poolFees,
1194
+ virtualPool.poolState.volatilityTracker,
1195
+ currentPoint,
1196
+ virtualPool.poolState.activationPoint,
1197
+ amount,
1198
+ tradeDirection
1199
+ );
1200
+ }
1201
+ function takeFee(feeNumerator, includedFeeAmount, hasReferral) {
1202
+ const { amount, ...fees } = getFeeOnAmount(
1203
+ feeNumerator,
1204
+ includedFeeAmount,
1205
+ hasReferral
1206
+ );
1207
+ return { amount, fees };
1208
+ }
1209
+ function addFee(feeNumerator, excludedFeeAmount, hasReferral) {
1210
+ const [amount, feeAmount] = getIncludedFeeAmount(
1211
+ feeNumerator,
1212
+ excludedFeeAmount
1213
+ );
1214
+ const [tradingFee, protocolFee, referralFee] = splitFees(
1215
+ feeAmount,
1216
+ hasReferral
1217
+ );
1218
+ return { amount, fees: { tradingFee, protocolFee, referralFee } };
1219
+ }
1220
+ function swapFromInput(virtualPool, config, tradeDirection, amountIn) {
1221
+ return tradeDirection === 0 /* BaseToQuote */ ? calculateBaseToQuoteFromAmountIn(
1222
+ config,
1223
+ virtualPool.poolState.sqrtPrice,
1224
+ amountIn
1225
+ ) : calculateQuoteToBaseFromAmountIn(
1226
+ config,
1227
+ virtualPool.poolState.sqrtPrice,
1228
+ amountIn,
1229
+ config.migrationSqrtPrice
1230
+ );
1231
+ }
1232
+ function getSwapResultFromExactInput(virtualPool, config, amountIn, feeMode, tradeDirection, currentPoint, eligibleForFirstSwapWithMinFee) {
1233
+ const feeNumerator = tradeFeeNumerator(
1234
+ virtualPool,
1235
+ config,
1236
+ currentPoint,
1237
+ tradeDirection,
1238
+ amountIn,
1239
+ false,
1240
+ eligibleForFirstSwapWithMinFee
1241
+ );
1242
+ let fees = NO_FEES;
1243
+ let actualAmountIn = amountIn;
1244
+ if (feeMode.feesOnInput) {
1245
+ ;
1246
+ ({ amount: actualAmountIn, fees } = takeFee(
1247
+ feeNumerator,
1248
+ amountIn,
1249
+ feeMode.hasReferral
1250
+ ));
1251
+ }
1252
+ const { outputAmount, nextSqrtPrice, amountLeft } = swapFromInput(
1253
+ virtualPool,
1254
+ config,
1255
+ tradeDirection,
1256
+ actualAmountIn
1257
+ );
1258
+ if (!amountLeft.isZero()) {
1259
+ throw new Error(ProgramError.InsufficientLiquidity);
1260
+ }
1261
+ let actualAmountOut = outputAmount;
1262
+ if (!feeMode.feesOnInput) {
1263
+ ;
1264
+ ({ amount: actualAmountOut, fees } = takeFee(
1265
+ feeNumerator,
1266
+ outputAmount,
1267
+ feeMode.hasReferral
1268
+ ));
1269
+ }
1270
+ return {
1271
+ amountLeft,
1272
+ includedFeeInputAmount: amountIn,
1273
+ excludedFeeInputAmount: actualAmountIn,
1274
+ outputAmount: actualAmountOut,
1275
+ nextSqrtPrice,
1276
+ ...fees
1277
+ };
1278
+ }
1279
+ function getSwapResult(virtualPool, config, amountIn, feeMode, tradeDirection, currentPoint, eligibleForFirstSwapWithMinFee) {
1280
+ const result = getSwapResultFromExactInput(
1281
+ virtualPool,
1282
+ config,
1283
+ amountIn,
1284
+ feeMode,
1285
+ tradeDirection,
1286
+ currentPoint,
1287
+ eligibleForFirstSwapWithMinFee
1288
+ );
1289
+ return {
1290
+ actualInputAmount: result.excludedFeeInputAmount,
1291
+ outputAmount: result.outputAmount,
1292
+ nextSqrtPrice: result.nextSqrtPrice,
1293
+ tradingFee: result.tradingFee,
1294
+ protocolFee: result.protocolFee,
1295
+ referralFee: result.referralFee
1296
+ };
1297
+ }
1298
+ function getSwapResultFromPartialInput(virtualPool, config, amountIn, feeMode, tradeDirection, currentPoint, eligibleForFirstSwapWithMinFee) {
1299
+ const feeNumerator = tradeFeeNumerator(
1300
+ virtualPool,
1301
+ config,
1302
+ currentPoint,
1303
+ tradeDirection,
1304
+ amountIn,
1305
+ false,
1306
+ eligibleForFirstSwapWithMinFee
1307
+ );
1308
+ let fees = NO_FEES;
1309
+ let actualAmountIn = amountIn;
1310
+ if (feeMode.feesOnInput) {
1311
+ ;
1312
+ ({ amount: actualAmountIn, fees } = takeFee(
1313
+ feeNumerator,
1314
+ amountIn,
1315
+ feeMode.hasReferral
1316
+ ));
1317
+ }
1318
+ const { outputAmount, nextSqrtPrice, amountLeft } = swapFromInput(
1319
+ virtualPool,
1320
+ config,
1321
+ tradeDirection,
1322
+ actualAmountIn
1323
+ );
1324
+ let includedFeeInputAmount = amountIn;
1325
+ if (!amountLeft.isZero()) {
1326
+ actualAmountIn = SafeMath.sub(actualAmountIn, amountLeft);
1327
+ if (feeMode.feesOnInput) {
1328
+ const partialFeeNumerator = tradeFeeNumerator(
1329
+ virtualPool,
1330
+ config,
1331
+ currentPoint,
1332
+ tradeDirection,
1333
+ actualAmountIn,
1334
+ true,
1335
+ eligibleForFirstSwapWithMinFee
1336
+ );
1337
+ ({ amount: includedFeeInputAmount, fees } = addFee(
1338
+ partialFeeNumerator,
1339
+ actualAmountIn,
1340
+ feeMode.hasReferral
1341
+ ));
1342
+ } else {
1343
+ includedFeeInputAmount = actualAmountIn;
1344
+ }
1345
+ }
1346
+ let actualAmountOut = outputAmount;
1347
+ if (!feeMode.feesOnInput) {
1348
+ ;
1349
+ ({ amount: actualAmountOut, fees } = takeFee(
1350
+ feeNumerator,
1351
+ outputAmount,
1352
+ feeMode.hasReferral
1353
+ ));
1354
+ }
1355
+ return {
1356
+ amountLeft,
1357
+ includedFeeInputAmount,
1358
+ excludedFeeInputAmount: actualAmountIn,
1359
+ outputAmount: actualAmountOut,
1360
+ nextSqrtPrice,
1361
+ ...fees
1362
+ };
1363
+ }
1364
+ function getSwapResultFromExactOutput(virtualPool, config, amountOut, feeMode, tradeDirection, currentPoint, eligibleForFirstSwapWithMinFee) {
1365
+ let fees = NO_FEES;
1366
+ let includedFeeOutAmount = amountOut;
1367
+ if (!feeMode.feesOnInput) {
1368
+ const feeNumerator = tradeFeeNumerator(
1369
+ virtualPool,
1370
+ config,
1371
+ currentPoint,
1372
+ tradeDirection,
1373
+ amountOut,
1374
+ true,
1375
+ eligibleForFirstSwapWithMinFee
1376
+ );
1377
+ ({ amount: includedFeeOutAmount, fees } = addFee(
1378
+ feeNumerator,
1379
+ amountOut,
1380
+ feeMode.hasReferral
1381
+ ));
1382
+ }
1383
+ const { amountIn, nextSqrtPrice } = tradeDirection === 0 /* BaseToQuote */ ? calculateBaseToQuoteFromAmountOut(
1384
+ config,
1385
+ virtualPool.poolState.sqrtPrice,
1386
+ includedFeeOutAmount
1387
+ ) : calculateQuoteToBaseFromAmountOut(
1388
+ config,
1389
+ virtualPool.poolState.sqrtPrice,
1390
+ includedFeeOutAmount
1391
+ );
1392
+ if (nextSqrtPrice.gt(config.migrationSqrtPrice)) {
1393
+ throw new Error(ProgramError.InsufficientLiquidity);
1394
+ }
1395
+ let includedFeeInputAmount = amountIn;
1396
+ if (feeMode.feesOnInput) {
1397
+ const feeNumerator = tradeFeeNumerator(
1398
+ virtualPool,
1399
+ config,
1400
+ currentPoint,
1401
+ tradeDirection,
1402
+ amountIn,
1403
+ true,
1404
+ eligibleForFirstSwapWithMinFee
1405
+ );
1406
+ ({ amount: includedFeeInputAmount, fees } = addFee(
1407
+ feeNumerator,
1408
+ amountIn,
1409
+ feeMode.hasReferral
1410
+ ));
1411
+ }
1412
+ return {
1413
+ amountLeft: ZERO2,
1414
+ includedFeeInputAmount,
1415
+ excludedFeeInputAmount: amountIn,
1416
+ outputAmount: amountOut,
1417
+ nextSqrtPrice,
1418
+ ...fees
1419
+ };
1420
+ }
1421
+ function calculateBaseToQuoteFromAmountIn(configState, currentSqrtPrice, amountIn) {
1422
+ let totalOutputAmount = ZERO2;
1423
+ let sqrtPrice = currentSqrtPrice;
1424
+ let amountLeft = amountIn;
1425
+ for (let i = configState.curve.length - 2; i >= 0; i--) {
1426
+ const point = configState.curve[i];
1427
+ const liquidity = configState.curve[i + 1].liquidity;
1428
+ if (point.sqrtPrice.isZero() || point.liquidity.isZero()) {
1429
+ continue;
1430
+ }
1431
+ if (!point.sqrtPrice.lt(sqrtPrice)) {
1432
+ continue;
1433
+ }
1434
+ const maxAmountIn = getDeltaAmountBaseUnsigned256(
1435
+ point.sqrtPrice,
1436
+ sqrtPrice,
1437
+ liquidity,
1438
+ 0 /* Up */
1439
+ );
1440
+ if (amountLeft.lt(maxAmountIn)) {
1441
+ const nextSqrtPrice = getNextSqrtPriceFromInput(
1442
+ sqrtPrice,
1443
+ liquidity,
1444
+ amountLeft,
1445
+ true
1446
+ );
1447
+ totalOutputAmount = addU64(
1448
+ totalOutputAmount,
1449
+ getDeltaAmountQuoteUnsigned(
1450
+ nextSqrtPrice,
1451
+ sqrtPrice,
1452
+ liquidity,
1453
+ 1 /* Down */
1454
+ )
1455
+ );
1456
+ sqrtPrice = nextSqrtPrice;
1457
+ amountLeft = ZERO2;
1458
+ break;
1459
+ }
1460
+ totalOutputAmount = addU64(
1461
+ totalOutputAmount,
1462
+ getDeltaAmountQuoteUnsigned(
1463
+ point.sqrtPrice,
1464
+ sqrtPrice,
1465
+ liquidity,
1466
+ 1 /* Down */
1467
+ )
1468
+ );
1469
+ sqrtPrice = point.sqrtPrice;
1470
+ amountLeft = SafeMath.sub(amountLeft, u64(maxAmountIn));
1471
+ }
1472
+ if (!amountLeft.isZero()) {
1473
+ const liquidity = configState.curve[0].liquidity;
1474
+ let nextSqrtPrice = getNextSqrtPriceFromInput(
1475
+ sqrtPrice,
1476
+ liquidity,
1477
+ amountLeft,
1478
+ true
1479
+ );
1480
+ if (nextSqrtPrice.lt(configState.sqrtStartPrice)) {
1481
+ nextSqrtPrice = configState.sqrtStartPrice;
1482
+ amountLeft = SafeMath.sub(
1483
+ amountLeft,
1484
+ getDeltaAmountBaseUnsigned(
1485
+ nextSqrtPrice,
1486
+ sqrtPrice,
1487
+ liquidity,
1488
+ 0 /* Up */
1489
+ )
1490
+ );
1491
+ } else {
1492
+ amountLeft = ZERO2;
1493
+ }
1494
+ totalOutputAmount = addU64(
1495
+ totalOutputAmount,
1496
+ getDeltaAmountQuoteUnsigned(
1497
+ nextSqrtPrice,
1498
+ sqrtPrice,
1499
+ liquidity,
1500
+ 1 /* Down */
1501
+ )
1502
+ );
1503
+ sqrtPrice = nextSqrtPrice;
1504
+ }
1505
+ return {
1506
+ amountLeft,
1507
+ outputAmount: totalOutputAmount,
1508
+ nextSqrtPrice: sqrtPrice
1509
+ };
1510
+ }
1511
+ function calculateQuoteToBaseFromAmountIn(configState, currentSqrtPrice, amountIn, stopSqrtPrice) {
1512
+ let totalOutputAmount = ZERO2;
1513
+ let sqrtPrice = currentSqrtPrice;
1514
+ let amountLeft = amountIn;
1515
+ for (const point of configState.curve) {
1516
+ if (point.sqrtPrice.isZero() || point.liquidity.isZero()) {
1517
+ break;
1518
+ }
1519
+ const referenceSqrtPrice = BN12.min(stopSqrtPrice, point.sqrtPrice);
1520
+ if (!referenceSqrtPrice.gt(sqrtPrice)) {
1521
+ continue;
1522
+ }
1523
+ const maxAmountIn = getDeltaAmountQuoteUnsigned256(
1524
+ sqrtPrice,
1525
+ referenceSqrtPrice,
1526
+ point.liquidity,
1527
+ 0 /* Up */
1528
+ );
1529
+ if (amountLeft.lt(maxAmountIn)) {
1530
+ const nextSqrtPrice = getNextSqrtPriceFromInput(
1531
+ sqrtPrice,
1532
+ point.liquidity,
1533
+ amountLeft,
1534
+ false
1535
+ );
1536
+ totalOutputAmount = addU64(
1537
+ totalOutputAmount,
1538
+ getDeltaAmountBaseUnsigned(
1539
+ sqrtPrice,
1540
+ nextSqrtPrice,
1541
+ point.liquidity,
1542
+ 1 /* Down */
1543
+ )
1544
+ );
1545
+ sqrtPrice = nextSqrtPrice;
1546
+ amountLeft = ZERO2;
1547
+ break;
1548
+ }
1549
+ totalOutputAmount = addU64(
1550
+ totalOutputAmount,
1551
+ getDeltaAmountBaseUnsigned(
1552
+ sqrtPrice,
1553
+ referenceSqrtPrice,
1554
+ point.liquidity,
1555
+ 1 /* Down */
1556
+ )
1557
+ );
1558
+ sqrtPrice = referenceSqrtPrice;
1559
+ amountLeft = SafeMath.sub(amountLeft, u64(maxAmountIn));
1560
+ if (sqrtPrice.eq(stopSqrtPrice)) {
1561
+ break;
1562
+ }
1563
+ }
1564
+ return {
1565
+ outputAmount: totalOutputAmount,
1566
+ nextSqrtPrice: sqrtPrice,
1567
+ amountLeft
1568
+ };
1569
+ }
1570
+ function calculateBaseToQuoteFromAmountOut(configState, currentSqrtPrice, outAmount) {
1571
+ let sqrtPrice = currentSqrtPrice;
1572
+ let amountLeft = outAmount;
1573
+ let totalAmountIn = ZERO2;
1574
+ for (let i = configState.curve.length - 2; i >= 0; i--) {
1575
+ const point = configState.curve[i];
1576
+ const liquidity = configState.curve[i + 1].liquidity;
1577
+ if (point.sqrtPrice.isZero() || point.liquidity.isZero()) {
1578
+ continue;
1579
+ }
1580
+ if (!point.sqrtPrice.lt(sqrtPrice)) {
1581
+ continue;
1582
+ }
1583
+ const maxAmountOut = getDeltaAmountQuoteUnsigned256(
1584
+ point.sqrtPrice,
1585
+ sqrtPrice,
1586
+ liquidity,
1587
+ 1 /* Down */
1588
+ );
1589
+ if (amountLeft.lt(maxAmountOut)) {
1590
+ const nextSqrtPrice = getNextSqrtPriceFromOutput(
1591
+ sqrtPrice,
1592
+ liquidity,
1593
+ amountLeft,
1594
+ true
1595
+ );
1596
+ totalAmountIn = addU64(
1597
+ totalAmountIn,
1598
+ getDeltaAmountBaseUnsigned(
1599
+ nextSqrtPrice,
1600
+ sqrtPrice,
1601
+ liquidity,
1602
+ 0 /* Up */
1603
+ )
1604
+ );
1605
+ sqrtPrice = nextSqrtPrice;
1606
+ amountLeft = ZERO2;
1607
+ break;
1608
+ }
1609
+ totalAmountIn = addU64(
1610
+ totalAmountIn,
1611
+ getDeltaAmountBaseUnsigned(
1612
+ point.sqrtPrice,
1613
+ sqrtPrice,
1614
+ liquidity,
1615
+ 0 /* Up */
1616
+ )
1617
+ );
1618
+ sqrtPrice = point.sqrtPrice;
1619
+ amountLeft = SafeMath.sub(amountLeft, u64(maxAmountOut));
1620
+ }
1621
+ if (!amountLeft.isZero()) {
1622
+ const liquidity = configState.curve[0].liquidity;
1623
+ const maxAmountOut = getDeltaAmountQuoteUnsigned256(
1624
+ configState.sqrtStartPrice,
1625
+ sqrtPrice,
1626
+ liquidity,
1627
+ 1 /* Down */
1628
+ );
1629
+ if (amountLeft.gt(maxAmountOut)) {
1630
+ throw new Error(ProgramError.InsufficientLiquidity);
1631
+ }
1632
+ const nextSqrtPrice = getNextSqrtPriceFromOutput(
1633
+ sqrtPrice,
1634
+ liquidity,
1635
+ amountLeft,
1636
+ true
1637
+ );
1638
+ if (nextSqrtPrice.lt(configState.sqrtStartPrice)) {
1639
+ throw new Error(ProgramError.InsufficientLiquidity);
1640
+ }
1641
+ totalAmountIn = addU64(
1642
+ totalAmountIn,
1643
+ getDeltaAmountBaseUnsigned(
1644
+ nextSqrtPrice,
1645
+ sqrtPrice,
1646
+ liquidity,
1647
+ 0 /* Up */
1648
+ )
1649
+ );
1650
+ sqrtPrice = nextSqrtPrice;
1651
+ }
1652
+ return { amountIn: totalAmountIn, nextSqrtPrice: sqrtPrice };
1653
+ }
1654
+ function calculateQuoteToBaseFromAmountOut(configState, currentSqrtPrice, outAmount) {
1655
+ let totalInAmount = ZERO2;
1656
+ let sqrtPrice = currentSqrtPrice;
1657
+ let amountLeft = outAmount;
1658
+ for (const point of configState.curve) {
1659
+ if (point.sqrtPrice.isZero() || point.liquidity.isZero()) {
1660
+ break;
1661
+ }
1662
+ if (!point.sqrtPrice.gt(sqrtPrice)) {
1663
+ continue;
1664
+ }
1665
+ const maxAmountOut = getDeltaAmountBaseUnsigned256(
1666
+ sqrtPrice,
1667
+ point.sqrtPrice,
1668
+ point.liquidity,
1669
+ 1 /* Down */
1670
+ );
1671
+ if (amountLeft.lt(maxAmountOut)) {
1672
+ const nextSqrtPrice = getNextSqrtPriceFromOutput(
1673
+ sqrtPrice,
1674
+ point.liquidity,
1675
+ amountLeft,
1676
+ false
1677
+ );
1678
+ totalInAmount = addU64(
1679
+ totalInAmount,
1680
+ getDeltaAmountQuoteUnsigned(
1681
+ sqrtPrice,
1682
+ nextSqrtPrice,
1683
+ point.liquidity,
1684
+ 0 /* Up */
1685
+ )
1686
+ );
1687
+ sqrtPrice = nextSqrtPrice;
1688
+ amountLeft = ZERO2;
1689
+ break;
1690
+ }
1691
+ totalInAmount = addU64(
1692
+ totalInAmount,
1693
+ getDeltaAmountQuoteUnsigned(
1694
+ sqrtPrice,
1695
+ point.sqrtPrice,
1696
+ point.liquidity,
1697
+ 0 /* Up */
1698
+ )
1699
+ );
1700
+ sqrtPrice = point.sqrtPrice;
1701
+ amountLeft = SafeMath.sub(amountLeft, u64(maxAmountOut));
1702
+ }
1703
+ if (!amountLeft.isZero()) {
1704
+ throw new Error(ProgramError.AmountLeftIsNotZero);
1705
+ }
1706
+ return { amountIn: totalInAmount, nextSqrtPrice: sqrtPrice };
1707
+ }
1708
+ function quoteExactIn(virtualPool, config, swapBaseForQuote, amountIn, slippageBps, hasReferral, currentPoint, eligibleForFirstSwapWithMinFee, transferFees) {
1709
+ const { tradeDirection, feeMode, input, output } = beginSwapQuote(
1710
+ virtualPool,
1711
+ config,
1712
+ swapBaseForQuote,
1713
+ amountIn,
1714
+ hasReferral,
1715
+ transferFees
1716
+ );
1717
+ const excludedAmountIn = calculateTransferFeeExcludedAmount(
1718
+ input,
1719
+ amountIn
1720
+ ).amount;
1721
+ if (excludedAmountIn.isZero()) {
1722
+ throw new Error(ProgramError.AmountIsZero);
1723
+ }
1724
+ const result = getSwapResultFromExactInput(
1725
+ virtualPool,
1726
+ config,
1727
+ excludedAmountIn,
1728
+ feeMode,
1729
+ tradeDirection,
1730
+ currentPoint,
1731
+ isFirstSwapWithMinFee(
1732
+ virtualPool,
1733
+ config,
1734
+ hasReferral,
1735
+ eligibleForFirstSwapWithMinFee
1736
+ )
1737
+ );
1738
+ const excludedAmountOut = calculateTransferFeeExcludedAmount(
1739
+ output,
1740
+ result.outputAmount
1741
+ ).amount;
1742
+ return {
1743
+ ...result,
1744
+ minimumAmountOut: minimumAmountOutWithSlippage(
1745
+ excludedAmountOut,
1746
+ slippageBps
1747
+ ),
1748
+ includedTransferFeeAmountIn: amountIn,
1749
+ excludedTransferFeeAmountOut: excludedAmountOut
1750
+ };
1751
+ }
1752
+ function swapQuote(virtualPool, config, swapBaseForQuote, amountIn, slippageBps = 0, hasReferral, currentPoint, eligibleForFirstSwapWithMinFee, transferFees) {
1753
+ const result = quoteExactIn(
1754
+ virtualPool,
1755
+ config,
1756
+ swapBaseForQuote,
1757
+ amountIn,
1758
+ slippageBps,
1759
+ hasReferral,
1760
+ currentPoint,
1761
+ eligibleForFirstSwapWithMinFee,
1762
+ transferFees
1763
+ );
1764
+ return {
1765
+ actualInputAmount: result.excludedFeeInputAmount,
1766
+ outputAmount: result.outputAmount,
1767
+ nextSqrtPrice: result.nextSqrtPrice,
1768
+ tradingFee: result.tradingFee,
1769
+ protocolFee: result.protocolFee,
1770
+ referralFee: result.referralFee,
1771
+ minimumAmountOut: result.minimumAmountOut,
1772
+ includedTransferFeeAmountIn: result.includedTransferFeeAmountIn,
1773
+ excludedTransferFeeAmountOut: result.excludedTransferFeeAmountOut
1774
+ };
1775
+ }
1776
+ function swapQuoteExactIn(virtualPool, config, swapBaseForQuote, amountIn, slippageBps = 0, hasReferral, currentPoint, eligibleForFirstSwapWithMinFee, transferFees) {
1777
+ return quoteExactIn(
1778
+ virtualPool,
1779
+ config,
1780
+ swapBaseForQuote,
1781
+ amountIn,
1782
+ slippageBps,
1783
+ hasReferral,
1784
+ currentPoint,
1785
+ eligibleForFirstSwapWithMinFee,
1786
+ transferFees
1787
+ );
1788
+ }
1789
+ function swapQuotePartialFill(virtualPool, config, swapBaseForQuote, amountIn, slippageBps = 0, hasReferral, currentPoint, eligibleForFirstSwapWithMinFee, transferFees) {
1790
+ const { tradeDirection, feeMode, input, output } = beginSwapQuote(
1791
+ virtualPool,
1792
+ config,
1793
+ swapBaseForQuote,
1794
+ amountIn,
1795
+ hasReferral,
1796
+ transferFees
1797
+ );
1798
+ const excludedAmountIn = calculateTransferFeeExcludedAmount(
1799
+ input,
1800
+ amountIn
1801
+ ).amount;
1802
+ if (excludedAmountIn.isZero()) {
1803
+ throw new Error(ProgramError.AmountIsZero);
1804
+ }
1805
+ const result = getSwapResultFromPartialInput(
1806
+ virtualPool,
1807
+ config,
1808
+ excludedAmountIn,
1809
+ feeMode,
1810
+ tradeDirection,
1811
+ currentPoint,
1812
+ isFirstSwapWithMinFee(
1813
+ virtualPool,
1814
+ config,
1815
+ hasReferral,
1816
+ eligibleForFirstSwapWithMinFee
1817
+ )
1818
+ );
1819
+ const includedAmountIn = result.amountLeft.isZero() ? amountIn : calculateTransferFeeIncludedAmount(
1820
+ input,
1821
+ result.includedFeeInputAmount
1822
+ ).amount;
1823
+ if (includedAmountIn.gt(amountIn)) {
1824
+ throw new Error(ProgramError.ExceededInputAmount);
1825
+ }
1826
+ const excludedAmountOut = calculateTransferFeeExcludedAmount(
1827
+ output,
1828
+ result.outputAmount
1829
+ ).amount;
1830
+ return {
1831
+ ...result,
1832
+ minimumAmountOut: minimumAmountOutWithSlippage(
1833
+ excludedAmountOut,
1834
+ slippageBps
1835
+ ),
1836
+ includedTransferFeeAmountIn: includedAmountIn,
1837
+ excludedTransferFeeAmountOut: excludedAmountOut
1838
+ };
1839
+ }
1840
+ function swapQuoteExactOut(virtualPool, config, swapBaseForQuote, outAmount, slippageBps = 0, hasReferral, currentPoint, eligibleForFirstSwapWithMinFee, transferFees) {
1841
+ const { tradeDirection, feeMode, input, output } = beginSwapQuote(
1842
+ virtualPool,
1843
+ config,
1844
+ swapBaseForQuote,
1845
+ outAmount,
1846
+ hasReferral,
1847
+ transferFees
1848
+ );
1849
+ const includedAmountOut = calculateTransferFeeIncludedAmount(
1850
+ output,
1851
+ outAmount
1852
+ ).amount;
1853
+ if (includedAmountOut.isZero()) {
1854
+ throw new Error(ProgramError.AmountIsZero);
1855
+ }
1856
+ const result = getSwapResultFromExactOutput(
1857
+ virtualPool,
1858
+ config,
1859
+ includedAmountOut,
1860
+ feeMode,
1861
+ tradeDirection,
1862
+ currentPoint,
1863
+ isFirstSwapWithMinFee(
1864
+ virtualPool,
1865
+ config,
1866
+ hasReferral,
1867
+ eligibleForFirstSwapWithMinFee
1868
+ )
1869
+ );
1870
+ const includedAmountIn = calculateTransferFeeIncludedAmount(
1871
+ input,
1872
+ result.includedFeeInputAmount
1873
+ ).amount;
1874
+ return {
1875
+ ...result,
1876
+ maximumAmountIn: maximumAmountInWithSlippage(
1877
+ includedAmountIn,
1878
+ slippageBps
1879
+ ),
1880
+ includedTransferFeeAmountIn: includedAmountIn,
1881
+ excludedTransferFeeAmountOut: outAmount
1882
+ };
1883
+ }
1884
+
1885
+ export {
1886
+ ActivationType,
1887
+ TokenType,
1888
+ CollectFeeMode,
1889
+ MigratedCollectFeeMode,
1890
+ DammV2DynamicFeeMode,
1891
+ DammV2BaseFeeMode,
1892
+ MigrationOption,
1893
+ BaseFeeMode,
1894
+ MigrationFeeOption,
1895
+ TokenDecimal,
1896
+ TradeDirection,
1897
+ Rounding,
1898
+ TokenAuthorityOption,
1899
+ SwapMode,
1900
+ TransferFeeWithheldAuthority,
1901
+ MigratedTransferFeeAuthorityOption,
1902
+ AccountsType,
1903
+ MAX_CURVE_POINT,
1904
+ RESOLUTION,
1905
+ ONE_Q64,
1906
+ FEE_DENOMINATOR,
1907
+ MAX_BASIS_POINT,
1908
+ MAX_BASE_TRANSFER_FEE_BPS,
1909
+ LEGACY_CONFIG_VERSION,
1910
+ U16_MAX,
1911
+ U24_MAX,
1912
+ U64_MAX,
1913
+ U128_MAX,
1914
+ MIN_SQRT_PRICE,
1915
+ MAX_SQRT_PRICE,
1916
+ MIN_FEE_BPS,
1917
+ MAX_FEE_BPS,
1918
+ MIN_FEE_NUMERATOR,
1919
+ MAX_FEE_NUMERATOR,
1920
+ MAX_RATE_LIMITER_DURATION_IN_SECONDS,
1921
+ MAX_RATE_LIMITER_DURATION_IN_SLOTS,
1922
+ DYNAMIC_FEE_FILTER_PERIOD_DEFAULT,
1923
+ DYNAMIC_FEE_DECAY_PERIOD_DEFAULT,
1924
+ DYNAMIC_FEE_REDUCTION_FACTOR_DEFAULT,
1925
+ DYNAMIC_FEE_SCALING_FACTOR,
1926
+ DYNAMIC_FEE_ROUNDING_OFFSET,
1927
+ BIN_STEP_BPS_DEFAULT,
1928
+ BIN_STEP_BPS_U128_DEFAULT,
1929
+ MAX_PRICE_CHANGE_BPS_DEFAULT,
1930
+ MAX_DYNAMIC_FEE_PERCENT,
1931
+ PROTOCOL_FEE_PERCENT,
1932
+ PARTNER_AND_CREATOR_SURPLUS_SHARE,
1933
+ HOST_FEE_PERCENT,
1934
+ SWAP_BUFFER_PERCENTAGE,
1935
+ PROTOCOL_LIQUIDITY_MIGRATION_FEE_BPS,
1936
+ DAMM_V2_COMPOUNDING_DEAD_LIQUIDITY,
1937
+ MAX_MIGRATION_FEE_PERCENTAGE,
1938
+ MAX_CREATOR_MIGRATION_FEE_PERCENTAGE,
1939
+ MIN_LOCKED_LIQUIDITY_BPS,
1940
+ SECONDS_PER_DAY,
1941
+ MAX_LOCK_DURATION_IN_SECONDS,
1942
+ PROTOCOL_POOL_CREATION_FEE_PERCENT,
1943
+ MIN_POOL_CREATION_FEE,
1944
+ MAX_POOL_CREATION_FEE,
1945
+ MIN_MIGRATED_POOL_FEE_BPS,
1946
+ MAX_MIGRATED_POOL_FEE_BPS,
1947
+ DYNAMIC_BONDING_CURVE_PROGRAM_ID,
1948
+ METAPLEX_PROGRAM_ID,
1949
+ DAMM_V1_PROGRAM_ID,
1950
+ DAMM_V2_PROGRAM_ID,
1951
+ VAULT_PROGRAM_ID,
1952
+ LOCKER_PROGRAM_ID,
1953
+ BASE_ADDRESS,
1954
+ DAMM_V1_MIGRATION_FEE_ADDRESS,
1955
+ DAMM_V2_MIGRATION_FEE_ADDRESS,
1956
+ DEFAULT_MIGRATED_POOL_FEE_PARAMS,
1957
+ DEFAULT_LIQUIDITY_VESTING_INFO_PARAMS,
1958
+ DEFAULT_MIGRATED_POOL_MARKET_CAP_FEE_SCHEDULER_PARAMS,
1959
+ ProgramError,
1960
+ SafeMath,
1961
+ pow,
1962
+ mulDiv,
1963
+ toNumerator,
1964
+ sqrt,
1965
+ getInitialLiquidityFromDeltaQuote,
1966
+ getInitialLiquidityFromDeltaBase,
1967
+ getDeltaAmountBaseUnsigned,
1968
+ getDeltaAmountBaseUnsigned256,
1969
+ getDeltaAmountQuoteUnsigned,
1970
+ getDeltaAmountQuoteUnsigned256,
1971
+ getNextSqrtPriceFromInput,
1972
+ getNextSqrtPriceFromOutput,
1973
+ getNextSqrtPriceFromQuoteAmountOutRoundingDown,
1974
+ getNextSqrtPriceFromBaseAmountOutRoundingUp,
1975
+ getNextSqrtPriceFromBaseAmountInRoundingUp,
1976
+ getNextSqrtPriceFromQuoteAmountInRoundingDown,
1977
+ liveCurve,
1978
+ isZeroTransferFee,
1979
+ getBaseTransferFee,
1980
+ getEpochTransferFee,
1981
+ resolveSwapTransferFees,
1982
+ calculateTransferFeeExcludedAmount,
1983
+ calculateTransferFeeIncludedAmount,
1984
+ getFeeSchedulerMinBaseFeeNumerator,
1985
+ getBaseFeeNumeratorByPeriod,
1986
+ getFeeNumeratorOnLinearFeeScheduler,
1987
+ getFeeNumeratorOnExponentialFeeScheduler,
1988
+ getBaseFeeNumerator,
1989
+ getExcludedFeeAmount,
1990
+ getIncludedFeeAmount,
1991
+ isRateLimiterApplied,
1992
+ isZeroRateLimiter,
1993
+ isNonZeroRateLimiter,
1994
+ getMaxIndex,
1995
+ getCheckedAmounts,
1996
+ getFeeNumeratorFromExcludedAmount,
1997
+ getRateLimiterExcludedFeeAmount,
1998
+ getMaxOutAmountWithMinBaseFee,
1999
+ getFeeNumeratorFromIncludedAmount,
2000
+ FeeRateLimiter,
2001
+ FeeScheduler,
2002
+ getBaseFeeHandler,
2003
+ isDynamicFeeEnabled,
2004
+ getVariableFeeNumerator,
2005
+ getFeeMode,
2006
+ getTotalFeeNumeratorFromIncludedFeeAmount,
2007
+ getTotalFeeNumeratorFromExcludedFeeAmount,
2008
+ getTotalFeeNumerator,
2009
+ getFeeOnAmount,
2010
+ splitFees,
2011
+ getSwapResultFromExactInput,
2012
+ getSwapResult,
2013
+ getSwapResultFromPartialInput,
2014
+ getSwapResultFromExactOutput,
2015
+ calculateBaseToQuoteFromAmountIn,
2016
+ calculateQuoteToBaseFromAmountIn,
2017
+ calculateBaseToQuoteFromAmountOut,
2018
+ calculateQuoteToBaseFromAmountOut,
2019
+ swapQuote,
2020
+ swapQuoteExactIn,
2021
+ swapQuotePartialFill,
2022
+ swapQuoteExactOut
2023
+ };
2024
+ //# sourceMappingURL=chunk-P4K4GKFH.js.map