@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.
- package/CHANGELOG.md +718 -0
- package/README.md +16 -7
- package/dist/chunk-IRVDOLO7.cjs +2024 -0
- package/dist/chunk-IRVDOLO7.cjs.map +1 -0
- package/dist/chunk-P4K4GKFH.js +2024 -0
- package/dist/chunk-P4K4GKFH.js.map +1 -0
- package/dist/index.cjs +16819 -26959
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +815 -20956
- package/dist/index.d.ts +815 -20956
- package/dist/index.js +17139 -27279
- package/dist/index.js.map +1 -1
- package/dist/math.cjs +125 -0
- package/dist/math.cjs.map +1 -0
- package/dist/math.d.cts +216 -0
- package/dist/math.d.ts +216 -0
- package/dist/math.js +125 -0
- package/dist/math.js.map +1 -0
- package/dist/swapQuote-CURAm57K.d.cts +6608 -0
- package/dist/swapQuote-CURAm57K.d.ts +6608 -0
- package/docs.md +7200 -0
- package/package.json +17 -5
|
@@ -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
|