@meteora-ag/cp-amm-sdk 1.1.5 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1887 -306
- package/dist/index.d.ts +1887 -306
- package/dist/index.js +2787 -924
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2791 -928
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -10
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
1
7
|
var __pow = Math.pow;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __spreadValues = (a, b) => {
|
|
10
|
+
for (var prop in b || (b = {}))
|
|
11
|
+
if (__hasOwnProp.call(b, prop))
|
|
12
|
+
__defNormalProp(a, prop, b[prop]);
|
|
13
|
+
if (__getOwnPropSymbols)
|
|
14
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
15
|
+
if (__propIsEnum.call(b, prop))
|
|
16
|
+
__defNormalProp(a, prop, b[prop]);
|
|
17
|
+
}
|
|
18
|
+
return a;
|
|
19
|
+
};
|
|
20
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
2
21
|
var __async = (__this, __arguments, generator) => {
|
|
3
22
|
return new Promise((resolve, reject) => {
|
|
4
23
|
var fulfilled = (value) => {
|
|
@@ -21,7 +40,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
21
40
|
};
|
|
22
41
|
|
|
23
42
|
// src/CpAmm.ts
|
|
24
|
-
import { Program
|
|
43
|
+
import { Program } from "@coral-xyz/anchor";
|
|
25
44
|
import { NATIVE_MINT as NATIVE_MINT2, TOKEN_2022_PROGRAM_ID as TOKEN_2022_PROGRAM_ID2 } from "@solana/spl-token";
|
|
26
45
|
import invariant from "invariant";
|
|
27
46
|
|
|
@@ -30,7 +49,7 @@ var cp_amm_default = {
|
|
|
30
49
|
address: "cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG",
|
|
31
50
|
metadata: {
|
|
32
51
|
name: "cp_amm",
|
|
33
|
-
version: "0.1.
|
|
52
|
+
version: "0.1.5",
|
|
34
53
|
spec: "0.1.0",
|
|
35
54
|
description: "Created with Anchor"
|
|
36
55
|
},
|
|
@@ -3618,6 +3637,147 @@ var cp_amm_default = {
|
|
|
3618
3637
|
}
|
|
3619
3638
|
]
|
|
3620
3639
|
},
|
|
3640
|
+
{
|
|
3641
|
+
name: "swap2",
|
|
3642
|
+
discriminator: [
|
|
3643
|
+
65,
|
|
3644
|
+
75,
|
|
3645
|
+
63,
|
|
3646
|
+
76,
|
|
3647
|
+
235,
|
|
3648
|
+
91,
|
|
3649
|
+
91,
|
|
3650
|
+
136
|
|
3651
|
+
],
|
|
3652
|
+
accounts: [
|
|
3653
|
+
{
|
|
3654
|
+
name: "pool_authority",
|
|
3655
|
+
address: "HLnpSz9h2S4hiLQ43rnSD9XkcUThA7B8hQMKmDaiTLcC"
|
|
3656
|
+
},
|
|
3657
|
+
{
|
|
3658
|
+
name: "pool",
|
|
3659
|
+
docs: [
|
|
3660
|
+
"Pool account"
|
|
3661
|
+
],
|
|
3662
|
+
writable: true
|
|
3663
|
+
},
|
|
3664
|
+
{
|
|
3665
|
+
name: "input_token_account",
|
|
3666
|
+
docs: [
|
|
3667
|
+
"The user token account for input token"
|
|
3668
|
+
],
|
|
3669
|
+
writable: true
|
|
3670
|
+
},
|
|
3671
|
+
{
|
|
3672
|
+
name: "output_token_account",
|
|
3673
|
+
docs: [
|
|
3674
|
+
"The user token account for output token"
|
|
3675
|
+
],
|
|
3676
|
+
writable: true
|
|
3677
|
+
},
|
|
3678
|
+
{
|
|
3679
|
+
name: "token_a_vault",
|
|
3680
|
+
docs: [
|
|
3681
|
+
"The vault token account for input token"
|
|
3682
|
+
],
|
|
3683
|
+
writable: true,
|
|
3684
|
+
relations: [
|
|
3685
|
+
"pool"
|
|
3686
|
+
]
|
|
3687
|
+
},
|
|
3688
|
+
{
|
|
3689
|
+
name: "token_b_vault",
|
|
3690
|
+
docs: [
|
|
3691
|
+
"The vault token account for output token"
|
|
3692
|
+
],
|
|
3693
|
+
writable: true,
|
|
3694
|
+
relations: [
|
|
3695
|
+
"pool"
|
|
3696
|
+
]
|
|
3697
|
+
},
|
|
3698
|
+
{
|
|
3699
|
+
name: "token_a_mint",
|
|
3700
|
+
docs: [
|
|
3701
|
+
"The mint of token a"
|
|
3702
|
+
]
|
|
3703
|
+
},
|
|
3704
|
+
{
|
|
3705
|
+
name: "token_b_mint",
|
|
3706
|
+
docs: [
|
|
3707
|
+
"The mint of token b"
|
|
3708
|
+
]
|
|
3709
|
+
},
|
|
3710
|
+
{
|
|
3711
|
+
name: "payer",
|
|
3712
|
+
docs: [
|
|
3713
|
+
"The user performing the swap"
|
|
3714
|
+
],
|
|
3715
|
+
signer: true
|
|
3716
|
+
},
|
|
3717
|
+
{
|
|
3718
|
+
name: "token_a_program",
|
|
3719
|
+
docs: [
|
|
3720
|
+
"Token a program"
|
|
3721
|
+
]
|
|
3722
|
+
},
|
|
3723
|
+
{
|
|
3724
|
+
name: "token_b_program",
|
|
3725
|
+
docs: [
|
|
3726
|
+
"Token b program"
|
|
3727
|
+
]
|
|
3728
|
+
},
|
|
3729
|
+
{
|
|
3730
|
+
name: "referral_token_account",
|
|
3731
|
+
docs: [
|
|
3732
|
+
"referral token account"
|
|
3733
|
+
],
|
|
3734
|
+
writable: true,
|
|
3735
|
+
optional: true
|
|
3736
|
+
},
|
|
3737
|
+
{
|
|
3738
|
+
name: "event_authority",
|
|
3739
|
+
pda: {
|
|
3740
|
+
seeds: [
|
|
3741
|
+
{
|
|
3742
|
+
kind: "const",
|
|
3743
|
+
value: [
|
|
3744
|
+
95,
|
|
3745
|
+
95,
|
|
3746
|
+
101,
|
|
3747
|
+
118,
|
|
3748
|
+
101,
|
|
3749
|
+
110,
|
|
3750
|
+
116,
|
|
3751
|
+
95,
|
|
3752
|
+
97,
|
|
3753
|
+
117,
|
|
3754
|
+
116,
|
|
3755
|
+
104,
|
|
3756
|
+
111,
|
|
3757
|
+
114,
|
|
3758
|
+
105,
|
|
3759
|
+
116,
|
|
3760
|
+
121
|
|
3761
|
+
]
|
|
3762
|
+
}
|
|
3763
|
+
]
|
|
3764
|
+
}
|
|
3765
|
+
},
|
|
3766
|
+
{
|
|
3767
|
+
name: "program"
|
|
3768
|
+
}
|
|
3769
|
+
],
|
|
3770
|
+
args: [
|
|
3771
|
+
{
|
|
3772
|
+
name: "params",
|
|
3773
|
+
type: {
|
|
3774
|
+
defined: {
|
|
3775
|
+
name: "SwapParameters2"
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
}
|
|
3779
|
+
]
|
|
3780
|
+
},
|
|
3621
3781
|
{
|
|
3622
3782
|
name: "update_reward_duration",
|
|
3623
3783
|
discriminator: [
|
|
@@ -4117,6 +4277,19 @@ var cp_amm_default = {
|
|
|
4117
4277
|
249
|
|
4118
4278
|
]
|
|
4119
4279
|
},
|
|
4280
|
+
{
|
|
4281
|
+
name: "EvtLiquidityChange",
|
|
4282
|
+
discriminator: [
|
|
4283
|
+
197,
|
|
4284
|
+
171,
|
|
4285
|
+
78,
|
|
4286
|
+
127,
|
|
4287
|
+
224,
|
|
4288
|
+
211,
|
|
4289
|
+
87,
|
|
4290
|
+
13
|
|
4291
|
+
]
|
|
4292
|
+
},
|
|
4120
4293
|
{
|
|
4121
4294
|
name: "EvtLockPosition",
|
|
4122
4295
|
discriminator: [
|
|
@@ -4195,6 +4368,19 @@ var cp_amm_default = {
|
|
|
4195
4368
|
147
|
|
4196
4369
|
]
|
|
4197
4370
|
},
|
|
4371
|
+
{
|
|
4372
|
+
name: "EvtSwap2",
|
|
4373
|
+
discriminator: [
|
|
4374
|
+
189,
|
|
4375
|
+
66,
|
|
4376
|
+
51,
|
|
4377
|
+
168,
|
|
4378
|
+
38,
|
|
4379
|
+
80,
|
|
4380
|
+
117,
|
|
4381
|
+
153
|
|
4382
|
+
]
|
|
4383
|
+
},
|
|
4198
4384
|
{
|
|
4199
4385
|
name: "EvtUpdateRewardDuration",
|
|
4200
4386
|
discriminator: [
|
|
@@ -4470,6 +4656,36 @@ var cp_amm_default = {
|
|
|
4470
4656
|
code: 6046,
|
|
4471
4657
|
name: "SamePosition",
|
|
4472
4658
|
msg: "Same position"
|
|
4659
|
+
},
|
|
4660
|
+
{
|
|
4661
|
+
code: 6047,
|
|
4662
|
+
name: "InvalidBaseFeeMode",
|
|
4663
|
+
msg: "Invalid base fee mode"
|
|
4664
|
+
},
|
|
4665
|
+
{
|
|
4666
|
+
code: 6048,
|
|
4667
|
+
name: "InvalidFeeRateLimiter",
|
|
4668
|
+
msg: "Invalid fee rate limiter"
|
|
4669
|
+
},
|
|
4670
|
+
{
|
|
4671
|
+
code: 6049,
|
|
4672
|
+
name: "FailToValidateSingleSwapInstruction",
|
|
4673
|
+
msg: "Fail to validate single swap instruction in rate limiter"
|
|
4674
|
+
},
|
|
4675
|
+
{
|
|
4676
|
+
code: 6050,
|
|
4677
|
+
name: "InvalidFeeScheduler",
|
|
4678
|
+
msg: "Invalid fee scheduler"
|
|
4679
|
+
},
|
|
4680
|
+
{
|
|
4681
|
+
code: 6051,
|
|
4682
|
+
name: "UndeterminedError",
|
|
4683
|
+
msg: "Undetermined error"
|
|
4684
|
+
},
|
|
4685
|
+
{
|
|
4686
|
+
code: 6052,
|
|
4687
|
+
name: "InvalidPoolVersion",
|
|
4688
|
+
msg: "Invalid pool version"
|
|
4473
4689
|
}
|
|
4474
4690
|
],
|
|
4475
4691
|
types: [
|
|
@@ -4516,7 +4732,7 @@ var cp_amm_default = {
|
|
|
4516
4732
|
type: "u64"
|
|
4517
4733
|
},
|
|
4518
4734
|
{
|
|
4519
|
-
name: "
|
|
4735
|
+
name: "base_fee_mode",
|
|
4520
4736
|
type: "u8"
|
|
4521
4737
|
},
|
|
4522
4738
|
{
|
|
@@ -4529,15 +4745,20 @@ var cp_amm_default = {
|
|
|
4529
4745
|
}
|
|
4530
4746
|
},
|
|
4531
4747
|
{
|
|
4532
|
-
name: "
|
|
4748
|
+
name: "first_factor",
|
|
4533
4749
|
type: "u16"
|
|
4534
4750
|
},
|
|
4535
4751
|
{
|
|
4536
|
-
name: "
|
|
4537
|
-
type:
|
|
4752
|
+
name: "second_factor",
|
|
4753
|
+
type: {
|
|
4754
|
+
array: [
|
|
4755
|
+
"u8",
|
|
4756
|
+
8
|
|
4757
|
+
]
|
|
4758
|
+
}
|
|
4538
4759
|
},
|
|
4539
4760
|
{
|
|
4540
|
-
name: "
|
|
4761
|
+
name: "third_factor",
|
|
4541
4762
|
type: "u64"
|
|
4542
4763
|
}
|
|
4543
4764
|
]
|
|
@@ -4553,19 +4774,24 @@ var cp_amm_default = {
|
|
|
4553
4774
|
type: "u64"
|
|
4554
4775
|
},
|
|
4555
4776
|
{
|
|
4556
|
-
name: "
|
|
4777
|
+
name: "first_factor",
|
|
4557
4778
|
type: "u16"
|
|
4558
4779
|
},
|
|
4559
4780
|
{
|
|
4560
|
-
name: "
|
|
4561
|
-
type:
|
|
4781
|
+
name: "second_factor",
|
|
4782
|
+
type: {
|
|
4783
|
+
array: [
|
|
4784
|
+
"u8",
|
|
4785
|
+
8
|
|
4786
|
+
]
|
|
4787
|
+
}
|
|
4562
4788
|
},
|
|
4563
4789
|
{
|
|
4564
|
-
name: "
|
|
4790
|
+
name: "third_factor",
|
|
4565
4791
|
type: "u64"
|
|
4566
4792
|
},
|
|
4567
4793
|
{
|
|
4568
|
-
name: "
|
|
4794
|
+
name: "base_fee_mode",
|
|
4569
4795
|
type: "u8"
|
|
4570
4796
|
}
|
|
4571
4797
|
]
|
|
@@ -4585,7 +4811,7 @@ var cp_amm_default = {
|
|
|
4585
4811
|
type: "u64"
|
|
4586
4812
|
},
|
|
4587
4813
|
{
|
|
4588
|
-
name: "
|
|
4814
|
+
name: "base_fee_mode",
|
|
4589
4815
|
type: "u8"
|
|
4590
4816
|
},
|
|
4591
4817
|
{
|
|
@@ -4598,15 +4824,20 @@ var cp_amm_default = {
|
|
|
4598
4824
|
}
|
|
4599
4825
|
},
|
|
4600
4826
|
{
|
|
4601
|
-
name: "
|
|
4827
|
+
name: "first_factor",
|
|
4602
4828
|
type: "u16"
|
|
4603
4829
|
},
|
|
4604
4830
|
{
|
|
4605
|
-
name: "
|
|
4606
|
-
type:
|
|
4831
|
+
name: "second_factor",
|
|
4832
|
+
type: {
|
|
4833
|
+
array: [
|
|
4834
|
+
"u8",
|
|
4835
|
+
8
|
|
4836
|
+
]
|
|
4837
|
+
}
|
|
4607
4838
|
},
|
|
4608
4839
|
{
|
|
4609
|
-
name: "
|
|
4840
|
+
name: "third_factor",
|
|
4610
4841
|
type: "u64"
|
|
4611
4842
|
},
|
|
4612
4843
|
{
|
|
@@ -5446,7 +5677,7 @@ var cp_amm_default = {
|
|
|
5446
5677
|
}
|
|
5447
5678
|
},
|
|
5448
5679
|
{
|
|
5449
|
-
name: "
|
|
5680
|
+
name: "EvtLiquidityChange",
|
|
5450
5681
|
type: {
|
|
5451
5682
|
kind: "struct",
|
|
5452
5683
|
fields: [
|
|
@@ -5463,58 +5694,50 @@ var cp_amm_default = {
|
|
|
5463
5694
|
type: "pubkey"
|
|
5464
5695
|
},
|
|
5465
5696
|
{
|
|
5466
|
-
name: "
|
|
5467
|
-
type: "
|
|
5697
|
+
name: "token_a_amount",
|
|
5698
|
+
type: "u64"
|
|
5468
5699
|
},
|
|
5469
5700
|
{
|
|
5470
|
-
name: "
|
|
5701
|
+
name: "token_b_amount",
|
|
5471
5702
|
type: "u64"
|
|
5472
5703
|
},
|
|
5473
5704
|
{
|
|
5474
|
-
name: "
|
|
5705
|
+
name: "transfer_fee_included_token_a_amount",
|
|
5475
5706
|
type: "u64"
|
|
5476
5707
|
},
|
|
5477
5708
|
{
|
|
5478
|
-
name: "
|
|
5479
|
-
type: "
|
|
5709
|
+
name: "transfer_fee_included_token_b_amount",
|
|
5710
|
+
type: "u64"
|
|
5480
5711
|
},
|
|
5481
5712
|
{
|
|
5482
|
-
name: "
|
|
5483
|
-
type: "
|
|
5713
|
+
name: "reserve_a_amount",
|
|
5714
|
+
type: "u64"
|
|
5484
5715
|
},
|
|
5485
5716
|
{
|
|
5486
|
-
name: "
|
|
5487
|
-
type: "
|
|
5488
|
-
}
|
|
5489
|
-
]
|
|
5490
|
-
}
|
|
5491
|
-
},
|
|
5492
|
-
{
|
|
5493
|
-
name: "EvtPermanentLockPosition",
|
|
5494
|
-
type: {
|
|
5495
|
-
kind: "struct",
|
|
5496
|
-
fields: [
|
|
5717
|
+
name: "reserve_b_amount",
|
|
5718
|
+
type: "u64"
|
|
5719
|
+
},
|
|
5497
5720
|
{
|
|
5498
|
-
name: "
|
|
5499
|
-
type: "
|
|
5721
|
+
name: "liquidity_delta",
|
|
5722
|
+
type: "u128"
|
|
5500
5723
|
},
|
|
5501
5724
|
{
|
|
5502
|
-
name: "
|
|
5503
|
-
type: "
|
|
5725
|
+
name: "token_a_amount_threshold",
|
|
5726
|
+
type: "u64"
|
|
5504
5727
|
},
|
|
5505
5728
|
{
|
|
5506
|
-
name: "
|
|
5507
|
-
type: "
|
|
5729
|
+
name: "token_b_amount_threshold",
|
|
5730
|
+
type: "u64"
|
|
5508
5731
|
},
|
|
5509
5732
|
{
|
|
5510
|
-
name: "
|
|
5511
|
-
type: "
|
|
5733
|
+
name: "change_type",
|
|
5734
|
+
type: "u8"
|
|
5512
5735
|
}
|
|
5513
5736
|
]
|
|
5514
5737
|
}
|
|
5515
5738
|
},
|
|
5516
5739
|
{
|
|
5517
|
-
name: "
|
|
5740
|
+
name: "EvtLockPosition",
|
|
5518
5741
|
type: {
|
|
5519
5742
|
kind: "struct",
|
|
5520
5743
|
fields: [
|
|
@@ -5531,15 +5754,83 @@ var cp_amm_default = {
|
|
|
5531
5754
|
type: "pubkey"
|
|
5532
5755
|
},
|
|
5533
5756
|
{
|
|
5534
|
-
name: "
|
|
5535
|
-
type:
|
|
5536
|
-
defined: {
|
|
5537
|
-
name: "RemoveLiquidityParameters"
|
|
5538
|
-
}
|
|
5539
|
-
}
|
|
5757
|
+
name: "vesting",
|
|
5758
|
+
type: "pubkey"
|
|
5540
5759
|
},
|
|
5541
5760
|
{
|
|
5542
|
-
name: "
|
|
5761
|
+
name: "cliff_point",
|
|
5762
|
+
type: "u64"
|
|
5763
|
+
},
|
|
5764
|
+
{
|
|
5765
|
+
name: "period_frequency",
|
|
5766
|
+
type: "u64"
|
|
5767
|
+
},
|
|
5768
|
+
{
|
|
5769
|
+
name: "cliff_unlock_liquidity",
|
|
5770
|
+
type: "u128"
|
|
5771
|
+
},
|
|
5772
|
+
{
|
|
5773
|
+
name: "liquidity_per_period",
|
|
5774
|
+
type: "u128"
|
|
5775
|
+
},
|
|
5776
|
+
{
|
|
5777
|
+
name: "number_of_period",
|
|
5778
|
+
type: "u16"
|
|
5779
|
+
}
|
|
5780
|
+
]
|
|
5781
|
+
}
|
|
5782
|
+
},
|
|
5783
|
+
{
|
|
5784
|
+
name: "EvtPermanentLockPosition",
|
|
5785
|
+
type: {
|
|
5786
|
+
kind: "struct",
|
|
5787
|
+
fields: [
|
|
5788
|
+
{
|
|
5789
|
+
name: "pool",
|
|
5790
|
+
type: "pubkey"
|
|
5791
|
+
},
|
|
5792
|
+
{
|
|
5793
|
+
name: "position",
|
|
5794
|
+
type: "pubkey"
|
|
5795
|
+
},
|
|
5796
|
+
{
|
|
5797
|
+
name: "lock_liquidity_amount",
|
|
5798
|
+
type: "u128"
|
|
5799
|
+
},
|
|
5800
|
+
{
|
|
5801
|
+
name: "total_permanent_locked_liquidity",
|
|
5802
|
+
type: "u128"
|
|
5803
|
+
}
|
|
5804
|
+
]
|
|
5805
|
+
}
|
|
5806
|
+
},
|
|
5807
|
+
{
|
|
5808
|
+
name: "EvtRemoveLiquidity",
|
|
5809
|
+
type: {
|
|
5810
|
+
kind: "struct",
|
|
5811
|
+
fields: [
|
|
5812
|
+
{
|
|
5813
|
+
name: "pool",
|
|
5814
|
+
type: "pubkey"
|
|
5815
|
+
},
|
|
5816
|
+
{
|
|
5817
|
+
name: "position",
|
|
5818
|
+
type: "pubkey"
|
|
5819
|
+
},
|
|
5820
|
+
{
|
|
5821
|
+
name: "owner",
|
|
5822
|
+
type: "pubkey"
|
|
5823
|
+
},
|
|
5824
|
+
{
|
|
5825
|
+
name: "params",
|
|
5826
|
+
type: {
|
|
5827
|
+
defined: {
|
|
5828
|
+
name: "RemoveLiquidityParameters"
|
|
5829
|
+
}
|
|
5830
|
+
}
|
|
5831
|
+
},
|
|
5832
|
+
{
|
|
5833
|
+
name: "token_a_amount",
|
|
5543
5834
|
type: "u64"
|
|
5544
5835
|
},
|
|
5545
5836
|
{
|
|
@@ -5673,6 +5964,70 @@ var cp_amm_default = {
|
|
|
5673
5964
|
]
|
|
5674
5965
|
}
|
|
5675
5966
|
},
|
|
5967
|
+
{
|
|
5968
|
+
name: "EvtSwap2",
|
|
5969
|
+
type: {
|
|
5970
|
+
kind: "struct",
|
|
5971
|
+
fields: [
|
|
5972
|
+
{
|
|
5973
|
+
name: "pool",
|
|
5974
|
+
type: "pubkey"
|
|
5975
|
+
},
|
|
5976
|
+
{
|
|
5977
|
+
name: "trade_direction",
|
|
5978
|
+
type: "u8"
|
|
5979
|
+
},
|
|
5980
|
+
{
|
|
5981
|
+
name: "collect_fee_mode",
|
|
5982
|
+
type: "u8"
|
|
5983
|
+
},
|
|
5984
|
+
{
|
|
5985
|
+
name: "has_referral",
|
|
5986
|
+
type: "bool"
|
|
5987
|
+
},
|
|
5988
|
+
{
|
|
5989
|
+
name: "params",
|
|
5990
|
+
type: {
|
|
5991
|
+
defined: {
|
|
5992
|
+
name: "SwapParameters2"
|
|
5993
|
+
}
|
|
5994
|
+
}
|
|
5995
|
+
},
|
|
5996
|
+
{
|
|
5997
|
+
name: "swap_result",
|
|
5998
|
+
type: {
|
|
5999
|
+
defined: {
|
|
6000
|
+
name: "SwapResult2"
|
|
6001
|
+
}
|
|
6002
|
+
}
|
|
6003
|
+
},
|
|
6004
|
+
{
|
|
6005
|
+
name: "included_transfer_fee_amount_in",
|
|
6006
|
+
type: "u64"
|
|
6007
|
+
},
|
|
6008
|
+
{
|
|
6009
|
+
name: "included_transfer_fee_amount_out",
|
|
6010
|
+
type: "u64"
|
|
6011
|
+
},
|
|
6012
|
+
{
|
|
6013
|
+
name: "excluded_transfer_fee_amount_out",
|
|
6014
|
+
type: "u64"
|
|
6015
|
+
},
|
|
6016
|
+
{
|
|
6017
|
+
name: "current_timestamp",
|
|
6018
|
+
type: "u64"
|
|
6019
|
+
},
|
|
6020
|
+
{
|
|
6021
|
+
name: "reserve_a_amount",
|
|
6022
|
+
type: "u64"
|
|
6023
|
+
},
|
|
6024
|
+
{
|
|
6025
|
+
name: "reserve_b_amount",
|
|
6026
|
+
type: "u64"
|
|
6027
|
+
}
|
|
6028
|
+
]
|
|
6029
|
+
}
|
|
6030
|
+
},
|
|
5676
6031
|
{
|
|
5677
6032
|
name: "EvtUpdateRewardDuration",
|
|
5678
6033
|
type: {
|
|
@@ -6023,17 +6378,19 @@ var cp_amm_default = {
|
|
|
6023
6378
|
],
|
|
6024
6379
|
type: "u8"
|
|
6025
6380
|
},
|
|
6381
|
+
{
|
|
6382
|
+
name: "version",
|
|
6383
|
+
docs: [
|
|
6384
|
+
"pool version, 0: max_fee is still capped at 50%, 1: max_fee is capped at 99%"
|
|
6385
|
+
],
|
|
6386
|
+
type: "u8"
|
|
6387
|
+
},
|
|
6026
6388
|
{
|
|
6027
6389
|
name: "_padding_0",
|
|
6028
6390
|
docs: [
|
|
6029
6391
|
"padding"
|
|
6030
6392
|
],
|
|
6031
|
-
type:
|
|
6032
|
-
array: [
|
|
6033
|
-
"u8",
|
|
6034
|
-
2
|
|
6035
|
-
]
|
|
6036
|
-
}
|
|
6393
|
+
type: "u8"
|
|
6037
6394
|
},
|
|
6038
6395
|
{
|
|
6039
6396
|
name: "fee_a_per_liquidity",
|
|
@@ -6854,6 +7211,35 @@ var cp_amm_default = {
|
|
|
6854
7211
|
]
|
|
6855
7212
|
}
|
|
6856
7213
|
},
|
|
7214
|
+
{
|
|
7215
|
+
name: "SwapParameters2",
|
|
7216
|
+
type: {
|
|
7217
|
+
kind: "struct",
|
|
7218
|
+
fields: [
|
|
7219
|
+
{
|
|
7220
|
+
name: "amount_0",
|
|
7221
|
+
docs: [
|
|
7222
|
+
"When it's exact in, partial fill, this will be amount_in. When it's exact out, this will be amount_out"
|
|
7223
|
+
],
|
|
7224
|
+
type: "u64"
|
|
7225
|
+
},
|
|
7226
|
+
{
|
|
7227
|
+
name: "amount_1",
|
|
7228
|
+
docs: [
|
|
7229
|
+
"When it's exact in, partial fill, this will be minimum_amount_out. When it's exact out, this will be maximum_amount_in"
|
|
7230
|
+
],
|
|
7231
|
+
type: "u64"
|
|
7232
|
+
},
|
|
7233
|
+
{
|
|
7234
|
+
name: "swap_mode",
|
|
7235
|
+
docs: [
|
|
7236
|
+
"Swap mode, refer [SwapMode]"
|
|
7237
|
+
],
|
|
7238
|
+
type: "u8"
|
|
7239
|
+
}
|
|
7240
|
+
]
|
|
7241
|
+
}
|
|
7242
|
+
},
|
|
6857
7243
|
{
|
|
6858
7244
|
name: "SwapResult",
|
|
6859
7245
|
docs: [
|
|
@@ -6889,6 +7275,50 @@ var cp_amm_default = {
|
|
|
6889
7275
|
]
|
|
6890
7276
|
}
|
|
6891
7277
|
},
|
|
7278
|
+
{
|
|
7279
|
+
name: "SwapResult2",
|
|
7280
|
+
type: {
|
|
7281
|
+
kind: "struct",
|
|
7282
|
+
fields: [
|
|
7283
|
+
{
|
|
7284
|
+
name: "included_fee_input_amount",
|
|
7285
|
+
type: "u64"
|
|
7286
|
+
},
|
|
7287
|
+
{
|
|
7288
|
+
name: "excluded_fee_input_amount",
|
|
7289
|
+
type: "u64"
|
|
7290
|
+
},
|
|
7291
|
+
{
|
|
7292
|
+
name: "amount_left",
|
|
7293
|
+
type: "u64"
|
|
7294
|
+
},
|
|
7295
|
+
{
|
|
7296
|
+
name: "output_amount",
|
|
7297
|
+
type: "u64"
|
|
7298
|
+
},
|
|
7299
|
+
{
|
|
7300
|
+
name: "next_sqrt_price",
|
|
7301
|
+
type: "u128"
|
|
7302
|
+
},
|
|
7303
|
+
{
|
|
7304
|
+
name: "trading_fee",
|
|
7305
|
+
type: "u64"
|
|
7306
|
+
},
|
|
7307
|
+
{
|
|
7308
|
+
name: "protocol_fee",
|
|
7309
|
+
type: "u64"
|
|
7310
|
+
},
|
|
7311
|
+
{
|
|
7312
|
+
name: "partner_fee",
|
|
7313
|
+
type: "u64"
|
|
7314
|
+
},
|
|
7315
|
+
{
|
|
7316
|
+
name: "referral_fee",
|
|
7317
|
+
type: "u64"
|
|
7318
|
+
}
|
|
7319
|
+
]
|
|
7320
|
+
}
|
|
7321
|
+
},
|
|
6892
7322
|
{
|
|
6893
7323
|
name: "TokenBadge",
|
|
6894
7324
|
docs: [
|
|
@@ -7055,7 +7485,8 @@ var cp_amm_default = {
|
|
|
7055
7485
|
// src/CpAmm.ts
|
|
7056
7486
|
import {
|
|
7057
7487
|
Transaction,
|
|
7058
|
-
SystemProgram as SystemProgram2
|
|
7488
|
+
SystemProgram as SystemProgram2,
|
|
7489
|
+
SYSVAR_INSTRUCTIONS_PUBKEY
|
|
7059
7490
|
} from "@solana/web3.js";
|
|
7060
7491
|
|
|
7061
7492
|
// src/types.ts
|
|
@@ -7069,52 +7500,85 @@ var ActivationPoint = /* @__PURE__ */ ((ActivationPoint2) => {
|
|
|
7069
7500
|
ActivationPoint2[ActivationPoint2["Slot"] = 1] = "Slot";
|
|
7070
7501
|
return ActivationPoint2;
|
|
7071
7502
|
})(ActivationPoint || {});
|
|
7072
|
-
var
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7503
|
+
var BaseFeeMode = /* @__PURE__ */ ((BaseFeeMode3) => {
|
|
7504
|
+
BaseFeeMode3[BaseFeeMode3["FeeSchedulerLinear"] = 0] = "FeeSchedulerLinear";
|
|
7505
|
+
BaseFeeMode3[BaseFeeMode3["FeeSchedulerExponential"] = 1] = "FeeSchedulerExponential";
|
|
7506
|
+
BaseFeeMode3[BaseFeeMode3["RateLimiter"] = 2] = "RateLimiter";
|
|
7507
|
+
return BaseFeeMode3;
|
|
7508
|
+
})(BaseFeeMode || {});
|
|
7509
|
+
var CollectFeeMode = /* @__PURE__ */ ((CollectFeeMode3) => {
|
|
7510
|
+
CollectFeeMode3[CollectFeeMode3["BothToken"] = 0] = "BothToken";
|
|
7511
|
+
CollectFeeMode3[CollectFeeMode3["OnlyB"] = 1] = "OnlyB";
|
|
7512
|
+
return CollectFeeMode3;
|
|
7081
7513
|
})(CollectFeeMode || {});
|
|
7082
|
-
var TradeDirection = /* @__PURE__ */ ((
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
return
|
|
7514
|
+
var TradeDirection = /* @__PURE__ */ ((TradeDirection3) => {
|
|
7515
|
+
TradeDirection3[TradeDirection3["AtoB"] = 0] = "AtoB";
|
|
7516
|
+
TradeDirection3[TradeDirection3["BtoA"] = 1] = "BtoA";
|
|
7517
|
+
return TradeDirection3;
|
|
7086
7518
|
})(TradeDirection || {});
|
|
7087
|
-
var ActivationType = /* @__PURE__ */ ((
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
return
|
|
7519
|
+
var ActivationType = /* @__PURE__ */ ((ActivationType3) => {
|
|
7520
|
+
ActivationType3[ActivationType3["Slot"] = 0] = "Slot";
|
|
7521
|
+
ActivationType3[ActivationType3["Timestamp"] = 1] = "Timestamp";
|
|
7522
|
+
return ActivationType3;
|
|
7091
7523
|
})(ActivationType || {});
|
|
7524
|
+
var PoolVersion = /* @__PURE__ */ ((PoolVersion5) => {
|
|
7525
|
+
PoolVersion5[PoolVersion5["V0"] = 0] = "V0";
|
|
7526
|
+
PoolVersion5[PoolVersion5["V1"] = 1] = "V1";
|
|
7527
|
+
return PoolVersion5;
|
|
7528
|
+
})(PoolVersion || {});
|
|
7529
|
+
var PoolStatus = /* @__PURE__ */ ((PoolStatus2) => {
|
|
7530
|
+
PoolStatus2[PoolStatus2["Enable"] = 0] = "Enable";
|
|
7531
|
+
PoolStatus2[PoolStatus2["Disable"] = 1] = "Disable";
|
|
7532
|
+
return PoolStatus2;
|
|
7533
|
+
})(PoolStatus || {});
|
|
7534
|
+
var SwapMode = /* @__PURE__ */ ((SwapMode2) => {
|
|
7535
|
+
SwapMode2[SwapMode2["ExactIn"] = 0] = "ExactIn";
|
|
7536
|
+
SwapMode2[SwapMode2["PartialFill"] = 1] = "PartialFill";
|
|
7537
|
+
SwapMode2[SwapMode2["ExactOut"] = 2] = "ExactOut";
|
|
7538
|
+
return SwapMode2;
|
|
7539
|
+
})(SwapMode || {});
|
|
7092
7540
|
|
|
7093
7541
|
// src/pda.ts
|
|
7094
7542
|
import { PublicKey as PublicKey2 } from "@solana/web3.js";
|
|
7095
7543
|
|
|
7096
7544
|
// src/constants.ts
|
|
7097
|
-
import { BN } from "@coral-xyz/anchor";
|
|
7098
7545
|
import { PublicKey } from "@solana/web3.js";
|
|
7546
|
+
import BN from "bn.js";
|
|
7099
7547
|
var CP_AMM_PROGRAM_ID = new PublicKey(
|
|
7100
7548
|
"cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG"
|
|
7101
7549
|
);
|
|
7102
7550
|
var LIQUIDITY_SCALE = 128;
|
|
7103
7551
|
var SCALE_OFFSET = 64;
|
|
7104
7552
|
var BASIS_POINT_MAX = 1e4;
|
|
7105
|
-
var MAX_FEE_NUMERATOR = 5e8;
|
|
7106
7553
|
var FEE_DENOMINATOR = 1e9;
|
|
7554
|
+
var ONE_Q64 = new BN(1).shln(SCALE_OFFSET);
|
|
7555
|
+
var MAX_EXPONENTIAL = new BN(524288);
|
|
7556
|
+
var MAX = new BN(2).pow(new BN(128)).sub(new BN(1));
|
|
7557
|
+
var MIN_FEE_BPS = 1;
|
|
7558
|
+
var MIN_FEE_NUMERATOR = 1e5;
|
|
7559
|
+
var MAX_FEE_BPS_V0 = 5e3;
|
|
7560
|
+
var MAX_FEE_NUMERATOR_V0 = 5e8;
|
|
7561
|
+
var MAX_FEE_BPS_V1 = 9900;
|
|
7562
|
+
var MAX_FEE_NUMERATOR_V1 = 99e7;
|
|
7107
7563
|
var MIN_SQRT_PRICE = new BN("4295048016");
|
|
7108
7564
|
var MAX_SQRT_PRICE = new BN("79226673521066979257578248091");
|
|
7109
7565
|
var MIN_CU_BUFFER = 5e4;
|
|
7110
7566
|
var MAX_CU_BUFFER = 2e5;
|
|
7567
|
+
var DYNAMIC_FEE_SCALING_FACTOR = new BN(1e11);
|
|
7568
|
+
var DYNAMIC_FEE_ROUNDING_OFFSET = new BN(99999999999);
|
|
7111
7569
|
var DYNAMIC_FEE_FILTER_PERIOD_DEFAULT = 10;
|
|
7112
7570
|
var DYNAMIC_FEE_DECAY_PERIOD_DEFAULT = 120;
|
|
7113
7571
|
var DYNAMIC_FEE_REDUCTION_FACTOR_DEFAULT = 5e3;
|
|
7114
7572
|
var BIN_STEP_BPS_DEFAULT = 1;
|
|
7115
7573
|
var BIN_STEP_BPS_U128_DEFAULT = new BN("1844674407370955");
|
|
7116
7574
|
var MAX_PRICE_CHANGE_BPS_DEFAULT = 1500;
|
|
7575
|
+
var U128_MAX = new BN("340282366920938463463374607431768211455");
|
|
7576
|
+
var U64_MAX = new BN("18446744073709551615");
|
|
7577
|
+
var U16_MAX = 65535;
|
|
7578
|
+
var MAX_RATE_LIMITER_DURATION_IN_SECONDS = 43200;
|
|
7579
|
+
var MAX_RATE_LIMITER_DURATION_IN_SLOTS = 108e3;
|
|
7117
7580
|
var SPLIT_POSITION_DENOMINATOR = 1e9;
|
|
7581
|
+
var CURRENT_POOL_VERSION = 0 /* V0 */;
|
|
7118
7582
|
|
|
7119
7583
|
// src/pda.ts
|
|
7120
7584
|
function getFirstKey(key1, key2) {
|
|
@@ -7225,10 +7689,10 @@ import {
|
|
|
7225
7689
|
function getTokenProgram(flag) {
|
|
7226
7690
|
return flag == 0 ? TOKEN_PROGRAM_ID : TOKEN_2022_PROGRAM_ID;
|
|
7227
7691
|
}
|
|
7228
|
-
var getTokenDecimals = (connection, mint) => __async(
|
|
7692
|
+
var getTokenDecimals = (connection, mint) => __async(null, null, function* () {
|
|
7229
7693
|
return (yield getMint(connection, mint)).decimals;
|
|
7230
7694
|
});
|
|
7231
|
-
var getOrCreateATAInstruction = (_0, _1, _2, ..._3) => __async(
|
|
7695
|
+
var getOrCreateATAInstruction = (_0, _1, _2, ..._3) => __async(null, [_0, _1, _2, ..._3], function* (connection, tokenMint, owner, payer = owner, allowOwnerOffCurve = true, tokenProgram) {
|
|
7232
7696
|
const toAccount = getAssociatedTokenAddressSync(
|
|
7233
7697
|
tokenMint,
|
|
7234
7698
|
owner,
|
|
@@ -7274,7 +7738,7 @@ var wrapSOLInstruction = (from, to, amount) => {
|
|
|
7274
7738
|
})
|
|
7275
7739
|
];
|
|
7276
7740
|
};
|
|
7277
|
-
var unwrapSOLInstruction = (_0, ..._1) => __async(
|
|
7741
|
+
var unwrapSOLInstruction = (_0, ..._1) => __async(null, [_0, ..._1], function* (owner, receiver = owner, allowOwnerOffCurve = true) {
|
|
7278
7742
|
const wSolATAAccount = getAssociatedTokenAddressSync(
|
|
7279
7743
|
NATIVE_MINT,
|
|
7280
7744
|
owner,
|
|
@@ -7345,106 +7809,442 @@ function getAllPositionNftAccountByOwner(connection, user) {
|
|
|
7345
7809
|
});
|
|
7346
7810
|
}
|
|
7347
7811
|
|
|
7348
|
-
// src/helpers/
|
|
7349
|
-
import {
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
var
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
|
|
7368
|
-
|
|
7369
|
-
|
|
7812
|
+
// src/helpers/computeUnits.ts
|
|
7813
|
+
import {
|
|
7814
|
+
ComputeBudgetProgram,
|
|
7815
|
+
PublicKey as PublicKey4,
|
|
7816
|
+
TransactionMessage,
|
|
7817
|
+
VersionedTransaction
|
|
7818
|
+
} from "@solana/web3.js";
|
|
7819
|
+
var getSimulationComputeUnits = (connection, instructions, payer, lookupTables, commitment = "confirmed") => __async(null, null, function* () {
|
|
7820
|
+
var _a, _b, _c;
|
|
7821
|
+
const testInstructions = [
|
|
7822
|
+
// Set an arbitrarily high number in simulation
|
|
7823
|
+
// so we can be sure the transaction will succeed
|
|
7824
|
+
// and get the real compute units used
|
|
7825
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: 14e5 }),
|
|
7826
|
+
...instructions
|
|
7827
|
+
];
|
|
7828
|
+
const testTransaction = new VersionedTransaction(
|
|
7829
|
+
new TransactionMessage({
|
|
7830
|
+
instructions: testInstructions,
|
|
7831
|
+
payerKey: payer,
|
|
7832
|
+
// RecentBlockhash can by any public key during simulation
|
|
7833
|
+
// since 'replaceRecentBlockhash' is set to 'true' below
|
|
7834
|
+
recentBlockhash: PublicKey4.default.toString()
|
|
7835
|
+
}).compileToV0Message(lookupTables)
|
|
7836
|
+
);
|
|
7837
|
+
const rpcResponse = yield connection.simulateTransaction(testTransaction, {
|
|
7838
|
+
replaceRecentBlockhash: true,
|
|
7839
|
+
sigVerify: false,
|
|
7840
|
+
commitment
|
|
7841
|
+
});
|
|
7842
|
+
if ((_a = rpcResponse == null ? void 0 : rpcResponse.value) == null ? void 0 : _a.err) {
|
|
7843
|
+
const logs = ((_b = rpcResponse.value.logs) == null ? void 0 : _b.join("\n \u2022 ")) || "No logs available";
|
|
7844
|
+
throw new Error(
|
|
7845
|
+
`Transaction simulation failed:
|
|
7846
|
+
\u2022${logs}` + JSON.stringify((_c = rpcResponse == null ? void 0 : rpcResponse.value) == null ? void 0 : _c.err)
|
|
7847
|
+
);
|
|
7370
7848
|
}
|
|
7371
|
-
|
|
7372
|
-
|
|
7849
|
+
return rpcResponse.value.unitsConsumed || null;
|
|
7850
|
+
});
|
|
7851
|
+
var getEstimatedComputeUnitUsageWithBuffer = (connection, instructions, feePayer, buffer) => __async(null, null, function* () {
|
|
7852
|
+
if (!buffer) {
|
|
7853
|
+
buffer = 0.1;
|
|
7854
|
+
}
|
|
7855
|
+
buffer = Math.max(0, buffer);
|
|
7856
|
+
buffer = Math.min(1, buffer);
|
|
7857
|
+
const estimatedComputeUnitUsage = yield getSimulationComputeUnits(
|
|
7858
|
+
connection,
|
|
7859
|
+
instructions,
|
|
7860
|
+
feePayer,
|
|
7861
|
+
[]
|
|
7862
|
+
);
|
|
7863
|
+
if (!estimatedComputeUnitUsage) {
|
|
7864
|
+
return 0;
|
|
7865
|
+
}
|
|
7866
|
+
let extraComputeUnitBuffer = estimatedComputeUnitUsage * buffer;
|
|
7867
|
+
if (extraComputeUnitBuffer > MAX_CU_BUFFER) {
|
|
7868
|
+
extraComputeUnitBuffer = MAX_CU_BUFFER;
|
|
7869
|
+
} else if (extraComputeUnitBuffer < MIN_CU_BUFFER) {
|
|
7870
|
+
extraComputeUnitBuffer = MIN_CU_BUFFER;
|
|
7871
|
+
}
|
|
7872
|
+
return estimatedComputeUnitUsage + extraComputeUnitBuffer;
|
|
7873
|
+
});
|
|
7874
|
+
var getEstimatedComputeUnitIxWithBuffer = (connection, instructions, feePayer, buffer) => __async(null, null, function* () {
|
|
7875
|
+
const units = yield getEstimatedComputeUnitUsageWithBuffer(
|
|
7876
|
+
connection,
|
|
7877
|
+
instructions,
|
|
7878
|
+
feePayer,
|
|
7879
|
+
buffer
|
|
7880
|
+
).catch((error) => {
|
|
7881
|
+
console.error("Error::getEstimatedComputeUnitUsageWithBuffer", error);
|
|
7882
|
+
return 14e5;
|
|
7883
|
+
});
|
|
7884
|
+
return ComputeBudgetProgram.setComputeUnitLimit({ units });
|
|
7885
|
+
});
|
|
7886
|
+
|
|
7887
|
+
// src/helpers/utils.ts
|
|
7888
|
+
import { BN as BN2 } from "@coral-xyz/anchor";
|
|
7889
|
+
import Decimal from "decimal.js";
|
|
7890
|
+
var getMaxAmountWithSlippage = (amount, rate) => {
|
|
7891
|
+
const slippage = (100 + rate) / 100 * BASIS_POINT_MAX;
|
|
7892
|
+
return amount.mul(new BN2(slippage)).div(new BN2(BASIS_POINT_MAX));
|
|
7893
|
+
};
|
|
7894
|
+
var getAmountWithSlippage = (amount, slippageBps, swapMode) => {
|
|
7895
|
+
let result;
|
|
7896
|
+
if (slippageBps > 0) {
|
|
7897
|
+
if (swapMode === 2 /* ExactOut */) {
|
|
7898
|
+
const slippageFactor = new BN2(BASIS_POINT_MAX + slippageBps);
|
|
7899
|
+
result = amount.mul(slippageFactor).div(new BN2(BASIS_POINT_MAX));
|
|
7900
|
+
} else {
|
|
7901
|
+
const slippageFactor = new BN2(BASIS_POINT_MAX - slippageBps);
|
|
7902
|
+
result = amount.mul(slippageFactor).div(new BN2(BASIS_POINT_MAX));
|
|
7903
|
+
}
|
|
7904
|
+
} else {
|
|
7905
|
+
result = amount;
|
|
7906
|
+
}
|
|
7907
|
+
return result;
|
|
7908
|
+
};
|
|
7909
|
+
var getPriceImpact = (amountIn, amountOut, currentSqrtPrice, aToB, tokenADecimal, tokenBDecimal) => {
|
|
7910
|
+
if (amountIn.eq(new BN2(0))) {
|
|
7911
|
+
return new Decimal(0);
|
|
7912
|
+
}
|
|
7913
|
+
if (amountOut.eq(new BN2(0))) {
|
|
7914
|
+
throw new Error("Amount out must be greater than 0");
|
|
7915
|
+
}
|
|
7916
|
+
const spotPrice = getPriceFromSqrtPrice(
|
|
7917
|
+
currentSqrtPrice,
|
|
7918
|
+
tokenADecimal,
|
|
7919
|
+
tokenBDecimal
|
|
7920
|
+
);
|
|
7921
|
+
const executionPrice = new Decimal(amountIn.toString()).div(new Decimal(amountOut.toString())).mul(
|
|
7922
|
+
Decimal.pow(
|
|
7923
|
+
10,
|
|
7924
|
+
aToB ? tokenBDecimal - tokenADecimal : tokenADecimal - tokenBDecimal
|
|
7925
|
+
)
|
|
7926
|
+
);
|
|
7927
|
+
let priceImpact;
|
|
7928
|
+
let actualExecutionPrice;
|
|
7929
|
+
if (aToB) {
|
|
7930
|
+
actualExecutionPrice = new Decimal(1).div(executionPrice);
|
|
7931
|
+
} else {
|
|
7932
|
+
actualExecutionPrice = executionPrice;
|
|
7933
|
+
}
|
|
7934
|
+
priceImpact = actualExecutionPrice.sub(spotPrice).abs().div(spotPrice).mul(100);
|
|
7935
|
+
return priceImpact;
|
|
7936
|
+
};
|
|
7937
|
+
var getPriceChange = (nextSqrtPrice, currentSqrtPrice) => {
|
|
7938
|
+
const diff = nextSqrtPrice.pow(new BN2(2)).sub(currentSqrtPrice.pow(new BN2(2))).abs();
|
|
7939
|
+
return new Decimal(diff.toString()).div(new Decimal(currentSqrtPrice.pow(new BN2(2)).toString())).mul(100).toNumber();
|
|
7940
|
+
};
|
|
7941
|
+
var getPriceFromSqrtPrice = (sqrtPrice, tokenADecimal, tokenBDecimal) => {
|
|
7942
|
+
const decimalSqrtPrice = new Decimal(sqrtPrice.toString());
|
|
7943
|
+
const price = decimalSqrtPrice.mul(decimalSqrtPrice).mul(new Decimal(__pow(10, tokenADecimal - tokenBDecimal))).div(Decimal.pow(2, 128));
|
|
7944
|
+
return price;
|
|
7945
|
+
};
|
|
7946
|
+
var getSqrtPriceFromPrice = (price, tokenADecimal, tokenBDecimal) => {
|
|
7947
|
+
const decimalPrice = new Decimal(price);
|
|
7948
|
+
const adjustedByDecimals = decimalPrice.div(
|
|
7949
|
+
new Decimal(__pow(10, tokenADecimal - tokenBDecimal))
|
|
7950
|
+
);
|
|
7951
|
+
const sqrtValue = Decimal.sqrt(adjustedByDecimals);
|
|
7952
|
+
const sqrtValueQ64 = sqrtValue.mul(Decimal.pow(2, 64));
|
|
7953
|
+
return new BN2(sqrtValueQ64.floor().toFixed());
|
|
7954
|
+
};
|
|
7955
|
+
var getUnClaimReward = (poolState, positionState) => {
|
|
7956
|
+
const totalPositionLiquidity = positionState.unlockedLiquidity.add(positionState.vestedLiquidity).add(positionState.permanentLockedLiquidity);
|
|
7957
|
+
const feeAPerTokenStored = new BN2(
|
|
7958
|
+
Buffer.from(poolState.feeAPerLiquidity).reverse()
|
|
7959
|
+
).sub(new BN2(Buffer.from(positionState.feeAPerTokenCheckpoint).reverse()));
|
|
7960
|
+
const feeBPerTokenStored = new BN2(
|
|
7961
|
+
Buffer.from(poolState.feeBPerLiquidity).reverse()
|
|
7962
|
+
).sub(new BN2(Buffer.from(positionState.feeBPerTokenCheckpoint).reverse()));
|
|
7963
|
+
const feeA = totalPositionLiquidity.mul(feeAPerTokenStored).shrn(LIQUIDITY_SCALE);
|
|
7964
|
+
const feeB = totalPositionLiquidity.mul(feeBPerTokenStored).shrn(LIQUIDITY_SCALE);
|
|
7965
|
+
return {
|
|
7966
|
+
feeTokenA: positionState.feeAPending.add(feeA),
|
|
7967
|
+
feeTokenB: positionState.feeBPending.add(feeB),
|
|
7968
|
+
rewards: positionState.rewardInfos.length > 0 ? positionState.rewardInfos.map((item) => item.rewardPendings) : []
|
|
7969
|
+
};
|
|
7970
|
+
};
|
|
7971
|
+
|
|
7972
|
+
// src/helpers/accountFilters.ts
|
|
7973
|
+
var positionByPoolFilter = (pool) => {
|
|
7974
|
+
return {
|
|
7975
|
+
memcmp: {
|
|
7976
|
+
bytes: pool.toBase58(),
|
|
7977
|
+
offset: 8
|
|
7978
|
+
}
|
|
7979
|
+
};
|
|
7980
|
+
};
|
|
7981
|
+
var vestingByPositionFilter = (position) => {
|
|
7982
|
+
return {
|
|
7983
|
+
memcmp: {
|
|
7984
|
+
bytes: position.toBase58(),
|
|
7985
|
+
offset: 8
|
|
7986
|
+
}
|
|
7987
|
+
};
|
|
7988
|
+
};
|
|
7989
|
+
|
|
7990
|
+
// src/helpers/token2022.ts
|
|
7991
|
+
import { BN as BN3 } from "@coral-xyz/anchor";
|
|
7992
|
+
import {
|
|
7993
|
+
calculateFee,
|
|
7994
|
+
getEpochFee,
|
|
7995
|
+
getTransferFeeConfig,
|
|
7996
|
+
MAX_FEE_BASIS_POINTS
|
|
7997
|
+
} from "@solana/spl-token";
|
|
7998
|
+
function calculatePreFeeAmount(transferFee, postFeeAmount) {
|
|
7999
|
+
if (postFeeAmount.isZero()) {
|
|
8000
|
+
return new BN3(0);
|
|
8001
|
+
}
|
|
8002
|
+
if (transferFee.transferFeeBasisPoints === 0) {
|
|
8003
|
+
return postFeeAmount;
|
|
8004
|
+
}
|
|
8005
|
+
const maximumFee = new BN3(transferFee.maximumFee.toString());
|
|
8006
|
+
if (transferFee.transferFeeBasisPoints === MAX_FEE_BASIS_POINTS) {
|
|
8007
|
+
return postFeeAmount.add(maximumFee);
|
|
8008
|
+
}
|
|
8009
|
+
const ONE_IN_BASIS_POINTS = new BN3(MAX_FEE_BASIS_POINTS);
|
|
8010
|
+
const numerator = postFeeAmount.mul(ONE_IN_BASIS_POINTS);
|
|
8011
|
+
const denominator = ONE_IN_BASIS_POINTS.sub(
|
|
8012
|
+
new BN3(transferFee.transferFeeBasisPoints)
|
|
8013
|
+
);
|
|
8014
|
+
const rawPreFeeAmount = numerator.add(denominator).sub(new BN3(1)).div(denominator);
|
|
8015
|
+
if (rawPreFeeAmount.sub(postFeeAmount).gte(maximumFee)) {
|
|
8016
|
+
return postFeeAmount.add(maximumFee);
|
|
8017
|
+
}
|
|
8018
|
+
return rawPreFeeAmount;
|
|
8019
|
+
}
|
|
8020
|
+
function calculateInverseFee(transferFee, postFeeAmount) {
|
|
8021
|
+
const preFeeAmount = calculatePreFeeAmount(transferFee, postFeeAmount);
|
|
8022
|
+
return new BN3(
|
|
8023
|
+
calculateFee(transferFee, BigInt(preFeeAmount.toString())).toString()
|
|
8024
|
+
);
|
|
8025
|
+
}
|
|
8026
|
+
function calculateTransferFeeIncludedAmount(transferFeeExcludedAmount, mint, currentEpoch) {
|
|
8027
|
+
if (transferFeeExcludedAmount.isZero()) {
|
|
8028
|
+
return {
|
|
8029
|
+
amount: new BN3(0),
|
|
8030
|
+
transferFee: new BN3(0)
|
|
8031
|
+
};
|
|
8032
|
+
}
|
|
8033
|
+
const transferFeeConfig = getTransferFeeConfig(mint);
|
|
8034
|
+
if (transferFeeConfig === null) {
|
|
8035
|
+
return {
|
|
8036
|
+
amount: transferFeeExcludedAmount,
|
|
8037
|
+
transferFee: new BN3(0)
|
|
8038
|
+
};
|
|
8039
|
+
}
|
|
8040
|
+
const epochFee = getEpochFee(transferFeeConfig, BigInt(currentEpoch));
|
|
8041
|
+
const transferFee = epochFee.transferFeeBasisPoints == MAX_FEE_BASIS_POINTS ? new BN3(epochFee.maximumFee.toString()) : calculateInverseFee(epochFee, transferFeeExcludedAmount);
|
|
8042
|
+
const transferFeeIncludedAmount = transferFeeExcludedAmount.add(transferFee);
|
|
8043
|
+
return {
|
|
8044
|
+
amount: transferFeeIncludedAmount,
|
|
8045
|
+
transferFee
|
|
8046
|
+
};
|
|
8047
|
+
}
|
|
8048
|
+
function calculateTransferFeeExcludedAmount(transferFeeIncludedAmount, mint, currentEpoch) {
|
|
8049
|
+
const transferFeeConfig = getTransferFeeConfig(mint);
|
|
8050
|
+
if (transferFeeConfig === null) {
|
|
8051
|
+
return {
|
|
8052
|
+
amount: transferFeeIncludedAmount,
|
|
8053
|
+
transferFee: new BN3(0)
|
|
8054
|
+
};
|
|
8055
|
+
}
|
|
8056
|
+
const transferFeeIncludedAmountN = BigInt(
|
|
8057
|
+
transferFeeIncludedAmount.toString()
|
|
8058
|
+
);
|
|
8059
|
+
const transferFee = calculateFee(
|
|
8060
|
+
getEpochFee(transferFeeConfig, BigInt(currentEpoch)),
|
|
8061
|
+
transferFeeIncludedAmountN
|
|
8062
|
+
);
|
|
8063
|
+
const transferFeeExcludedAmount = new BN3(
|
|
8064
|
+
(transferFeeIncludedAmountN - transferFee).toString()
|
|
8065
|
+
);
|
|
8066
|
+
return {
|
|
8067
|
+
amount: transferFeeExcludedAmount,
|
|
8068
|
+
transferFee: new BN3(transferFee.toString())
|
|
8069
|
+
};
|
|
8070
|
+
}
|
|
8071
|
+
|
|
8072
|
+
// src/helpers/vestings.ts
|
|
8073
|
+
import { BN as BN4 } from "@coral-xyz/anchor";
|
|
8074
|
+
import { min } from "bn.js";
|
|
8075
|
+
function isVestingComplete(vestingData, currentPoint) {
|
|
8076
|
+
const cliffPoint = vestingData.cliffPoint;
|
|
8077
|
+
const periodFrequency = vestingData.periodFrequency;
|
|
8078
|
+
const numberOfPeriods = vestingData.numberOfPeriod;
|
|
8079
|
+
const endPoint = cliffPoint.add(periodFrequency.muln(numberOfPeriods));
|
|
8080
|
+
return currentPoint.gte(endPoint);
|
|
8081
|
+
}
|
|
8082
|
+
function getTotalLockedLiquidity(vestingData) {
|
|
8083
|
+
return vestingData.cliffUnlockLiquidity.add(
|
|
8084
|
+
vestingData.liquidityPerPeriod.mul(new BN4(vestingData.numberOfPeriod))
|
|
8085
|
+
);
|
|
8086
|
+
}
|
|
8087
|
+
function getAvailableVestingLiquidity(vestingData, currentPoint) {
|
|
8088
|
+
const {
|
|
8089
|
+
cliffPoint,
|
|
8090
|
+
periodFrequency,
|
|
8091
|
+
cliffUnlockLiquidity,
|
|
8092
|
+
liquidityPerPeriod,
|
|
8093
|
+
numberOfPeriod,
|
|
8094
|
+
totalReleasedLiquidity
|
|
8095
|
+
} = vestingData;
|
|
8096
|
+
if (currentPoint.lt(cliffPoint)) {
|
|
8097
|
+
return new BN4(0);
|
|
8098
|
+
}
|
|
8099
|
+
if (periodFrequency.isZero()) {
|
|
8100
|
+
return cliffUnlockLiquidity;
|
|
8101
|
+
}
|
|
8102
|
+
let passedPeriod = new BN4(currentPoint).sub(cliffPoint).div(periodFrequency);
|
|
8103
|
+
passedPeriod = min(passedPeriod, new BN4(numberOfPeriod));
|
|
8104
|
+
const unlockedLiquidity = cliffUnlockLiquidity.add(
|
|
8105
|
+
passedPeriod.mul(liquidityPerPeriod)
|
|
8106
|
+
);
|
|
8107
|
+
const availableReleasingLiquidity = unlockedLiquidity.sub(
|
|
8108
|
+
totalReleasedLiquidity
|
|
8109
|
+
);
|
|
8110
|
+
return availableReleasingLiquidity;
|
|
8111
|
+
}
|
|
8112
|
+
|
|
8113
|
+
// src/helpers/validation.ts
|
|
8114
|
+
import BN14 from "bn.js";
|
|
8115
|
+
|
|
8116
|
+
// src/math/poolFees/baseFee.ts
|
|
8117
|
+
import BN9 from "bn.js";
|
|
8118
|
+
|
|
8119
|
+
// src/math/poolFees/rateLimiter.ts
|
|
8120
|
+
import BN7 from "bn.js";
|
|
8121
|
+
|
|
8122
|
+
// src/math/feeMath.ts
|
|
8123
|
+
import { BN as BN6 } from "@coral-xyz/anchor";
|
|
8124
|
+
|
|
8125
|
+
// src/math/utilsMath.ts
|
|
8126
|
+
import Decimal2 from "decimal.js";
|
|
8127
|
+
import BN5 from "bn.js";
|
|
8128
|
+
function mulDiv(x, y, denominator, rounding) {
|
|
8129
|
+
const { div, mod } = x.mul(y).divmod(denominator);
|
|
8130
|
+
if (rounding == 0 /* Up */ && !mod.isZero()) {
|
|
8131
|
+
return div.add(new BN5(1));
|
|
8132
|
+
}
|
|
8133
|
+
return div;
|
|
8134
|
+
}
|
|
8135
|
+
function q64ToDecimal(num, decimalPlaces) {
|
|
8136
|
+
return new Decimal2(num.toString()).div(Decimal2.pow(2, 64)).toDecimalPlaces(decimalPlaces);
|
|
8137
|
+
}
|
|
8138
|
+
function decimalToQ64(num) {
|
|
8139
|
+
return new BN5(num.mul(Decimal2.pow(2, 64)).floor().toFixed());
|
|
8140
|
+
}
|
|
8141
|
+
function sqrt(value) {
|
|
8142
|
+
if (value.isZero()) {
|
|
8143
|
+
return new BN5(0);
|
|
8144
|
+
}
|
|
8145
|
+
if (value.eq(new BN5(1))) {
|
|
8146
|
+
return new BN5(1);
|
|
8147
|
+
}
|
|
8148
|
+
let x = value;
|
|
8149
|
+
let y = value.add(new BN5(1)).div(new BN5(2));
|
|
8150
|
+
while (y.lt(x)) {
|
|
8151
|
+
x = y;
|
|
8152
|
+
y = x.add(value.div(x)).div(new BN5(2));
|
|
8153
|
+
}
|
|
8154
|
+
return x;
|
|
8155
|
+
}
|
|
8156
|
+
function pow(base, exp) {
|
|
8157
|
+
let invert = exp.isNeg();
|
|
8158
|
+
if (exp.isZero()) {
|
|
8159
|
+
return ONE_Q64;
|
|
8160
|
+
}
|
|
8161
|
+
exp = invert ? exp.abs() : exp;
|
|
8162
|
+
if (exp.gt(MAX_EXPONENTIAL)) {
|
|
8163
|
+
return new BN5(0);
|
|
8164
|
+
}
|
|
8165
|
+
let squaredBase = base;
|
|
8166
|
+
let result = ONE_Q64;
|
|
8167
|
+
if (squaredBase.gte(result)) {
|
|
8168
|
+
squaredBase = MAX.div(squaredBase);
|
|
8169
|
+
invert = !invert;
|
|
8170
|
+
}
|
|
8171
|
+
if (!exp.and(new BN5(1)).isZero()) {
|
|
8172
|
+
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7373
8173
|
}
|
|
7374
8174
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7375
|
-
if (!exp.and(new
|
|
8175
|
+
if (!exp.and(new BN5(2)).isZero()) {
|
|
7376
8176
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7377
8177
|
}
|
|
7378
8178
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7379
|
-
if (!exp.and(new
|
|
8179
|
+
if (!exp.and(new BN5(4)).isZero()) {
|
|
7380
8180
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7381
8181
|
}
|
|
7382
8182
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7383
|
-
if (!exp.and(new
|
|
8183
|
+
if (!exp.and(new BN5(8)).isZero()) {
|
|
7384
8184
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7385
8185
|
}
|
|
7386
8186
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7387
|
-
if (!exp.and(new
|
|
8187
|
+
if (!exp.and(new BN5(16)).isZero()) {
|
|
7388
8188
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7389
8189
|
}
|
|
7390
8190
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7391
|
-
if (!exp.and(new
|
|
8191
|
+
if (!exp.and(new BN5(32)).isZero()) {
|
|
7392
8192
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7393
8193
|
}
|
|
7394
8194
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7395
|
-
if (!exp.and(new
|
|
8195
|
+
if (!exp.and(new BN5(64)).isZero()) {
|
|
7396
8196
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7397
8197
|
}
|
|
7398
8198
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7399
|
-
if (!exp.and(new
|
|
8199
|
+
if (!exp.and(new BN5(128)).isZero()) {
|
|
7400
8200
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7401
8201
|
}
|
|
7402
8202
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7403
|
-
if (!exp.and(new
|
|
8203
|
+
if (!exp.and(new BN5(256)).isZero()) {
|
|
7404
8204
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7405
8205
|
}
|
|
7406
8206
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7407
|
-
if (!exp.and(new
|
|
8207
|
+
if (!exp.and(new BN5(512)).isZero()) {
|
|
7408
8208
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7409
8209
|
}
|
|
7410
8210
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7411
|
-
if (!exp.and(new
|
|
8211
|
+
if (!exp.and(new BN5(1024)).isZero()) {
|
|
7412
8212
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7413
8213
|
}
|
|
7414
8214
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7415
|
-
if (!exp.and(new
|
|
8215
|
+
if (!exp.and(new BN5(2048)).isZero()) {
|
|
7416
8216
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7417
8217
|
}
|
|
7418
8218
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7419
|
-
if (!exp.and(new
|
|
8219
|
+
if (!exp.and(new BN5(4096)).isZero()) {
|
|
7420
8220
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7421
8221
|
}
|
|
7422
8222
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7423
|
-
if (!exp.and(new
|
|
8223
|
+
if (!exp.and(new BN5(8192)).isZero()) {
|
|
7424
8224
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7425
8225
|
}
|
|
7426
8226
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7427
|
-
if (!exp.and(new
|
|
8227
|
+
if (!exp.and(new BN5(16384)).isZero()) {
|
|
7428
8228
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7429
8229
|
}
|
|
7430
8230
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7431
|
-
if (!exp.and(new
|
|
8231
|
+
if (!exp.and(new BN5(32768)).isZero()) {
|
|
7432
8232
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7433
8233
|
}
|
|
7434
8234
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7435
|
-
if (!exp.and(new
|
|
8235
|
+
if (!exp.and(new BN5(65536)).isZero()) {
|
|
7436
8236
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7437
8237
|
}
|
|
7438
8238
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7439
|
-
if (!exp.and(new
|
|
8239
|
+
if (!exp.and(new BN5(131072)).isZero()) {
|
|
7440
8240
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7441
8241
|
}
|
|
7442
8242
|
squaredBase = squaredBase.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7443
|
-
if (!exp.and(new
|
|
8243
|
+
if (!exp.and(new BN5(262144)).isZero()) {
|
|
7444
8244
|
result = result.mul(squaredBase).shrn(SCALE_OFFSET);
|
|
7445
8245
|
}
|
|
7446
8246
|
if (result.isZero()) {
|
|
7447
|
-
return new
|
|
8247
|
+
return new BN5(0);
|
|
7448
8248
|
}
|
|
7449
8249
|
if (invert) {
|
|
7450
8250
|
result = MAX.div(result);
|
|
@@ -7452,772 +8252,1695 @@ function pow(base, exp) {
|
|
|
7452
8252
|
return result;
|
|
7453
8253
|
}
|
|
7454
8254
|
|
|
7455
|
-
// src/math/
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
return
|
|
7464
|
-
}
|
|
7465
|
-
function q64ToDecimal(num, decimalPlaces) {
|
|
7466
|
-
return new Decimal(num.toString()).div(Decimal.pow(2, 64)).toDecimalPlaces(decimalPlaces);
|
|
7467
|
-
}
|
|
7468
|
-
function decimalToQ64(num) {
|
|
7469
|
-
return new BN3(num.mul(Decimal.pow(2, 64)).floor().toFixed());
|
|
7470
|
-
}
|
|
7471
|
-
|
|
7472
|
-
// src/helpers/curve.ts
|
|
7473
|
-
import { BN as BN4 } from "@coral-xyz/anchor";
|
|
7474
|
-
function getNextSqrtPrice(amount, sqrtPrice, liquidity, aToB) {
|
|
7475
|
-
let result;
|
|
7476
|
-
if (aToB) {
|
|
7477
|
-
const product = amount.mul(sqrtPrice);
|
|
7478
|
-
const denominator = liquidity.add(product);
|
|
7479
|
-
const numerator = liquidity.mul(sqrtPrice);
|
|
7480
|
-
result = numerator.add(denominator.sub(new BN4(1))).div(denominator);
|
|
7481
|
-
} else {
|
|
7482
|
-
const quotient = amount.shln(SCALE_OFFSET * 2).div(liquidity);
|
|
7483
|
-
result = sqrtPrice.add(quotient);
|
|
7484
|
-
}
|
|
7485
|
-
return result;
|
|
7486
|
-
}
|
|
7487
|
-
function getLiquidityDeltaFromAmountA(amountA, lowerSqrtPrice, upperSqrtPrice) {
|
|
7488
|
-
const product = amountA.mul(lowerSqrtPrice).mul(upperSqrtPrice);
|
|
7489
|
-
const denominator = upperSqrtPrice.sub(lowerSqrtPrice);
|
|
7490
|
-
return product.div(denominator);
|
|
7491
|
-
}
|
|
7492
|
-
function getLiquidityDeltaFromAmountB(amountB, lowerSqrtPrice, upperSqrtPrice) {
|
|
7493
|
-
const denominator = upperSqrtPrice.sub(lowerSqrtPrice);
|
|
7494
|
-
const product = amountB.shln(128);
|
|
7495
|
-
return product.div(denominator);
|
|
7496
|
-
}
|
|
7497
|
-
function getAmountAFromLiquidityDelta(liquidity, currentSqrtPrice, maxSqrtPrice, rounding) {
|
|
7498
|
-
const product = liquidity.mul(maxSqrtPrice.sub(currentSqrtPrice));
|
|
7499
|
-
const denominator = currentSqrtPrice.mul(maxSqrtPrice);
|
|
7500
|
-
if (rounding == 0 /* Up */) {
|
|
7501
|
-
return product.add(denominator.sub(new BN4(1))).div(denominator);
|
|
7502
|
-
}
|
|
7503
|
-
return product.div(denominator);
|
|
7504
|
-
}
|
|
7505
|
-
function getAmountBFromLiquidityDelta(liquidity, currentSqrtPrice, minSqrtPrice, rounding) {
|
|
7506
|
-
const one = new BN4(1).shln(128);
|
|
7507
|
-
const deltaPrice = currentSqrtPrice.sub(minSqrtPrice);
|
|
7508
|
-
const result = liquidity.mul(deltaPrice);
|
|
7509
|
-
if (rounding == 0 /* Up */) {
|
|
7510
|
-
return result.add(one.sub(new BN4(1))).div(one);
|
|
7511
|
-
}
|
|
7512
|
-
return result.shrn(128);
|
|
7513
|
-
}
|
|
7514
|
-
function getNextSqrtPriceFromAmountBRoundingUp(sqrtPrice, liquidity, amount) {
|
|
7515
|
-
const quotient = amount.shln(128).add(liquidity).sub(new BN4(1)).div(liquidity);
|
|
7516
|
-
const result = sqrtPrice.sub(quotient);
|
|
7517
|
-
if (result.isNeg()) {
|
|
7518
|
-
throw new Error("sqrt price cannot be negative");
|
|
7519
|
-
}
|
|
7520
|
-
return result;
|
|
7521
|
-
}
|
|
7522
|
-
function getNextSqrtPriceFromAmountARoundingDown(sqrtPrice, liquidity, amount) {
|
|
7523
|
-
if (amount.isZero()) {
|
|
7524
|
-
return sqrtPrice;
|
|
7525
|
-
}
|
|
7526
|
-
const product = amount.mul(sqrtPrice);
|
|
7527
|
-
const denominator = liquidity.sub(product);
|
|
7528
|
-
if (denominator.isNeg() || denominator.isZero()) {
|
|
7529
|
-
throw new Error("Invalid denominator in sqrt price calculation");
|
|
7530
|
-
}
|
|
7531
|
-
const numerator = liquidity.mul(sqrtPrice);
|
|
7532
|
-
const result = numerator.div(denominator);
|
|
7533
|
-
return result;
|
|
8255
|
+
// src/math/feeMath.ts
|
|
8256
|
+
function toNumerator(bps, feeDenominator) {
|
|
8257
|
+
const numerator = mulDiv(
|
|
8258
|
+
bps,
|
|
8259
|
+
feeDenominator,
|
|
8260
|
+
new BN6(BASIS_POINT_MAX),
|
|
8261
|
+
1 /* Down */
|
|
8262
|
+
);
|
|
8263
|
+
return numerator;
|
|
7534
8264
|
}
|
|
7535
|
-
function
|
|
7536
|
-
if (
|
|
7537
|
-
|
|
7538
|
-
}
|
|
7539
|
-
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
sqrtPrice,
|
|
7548
|
-
liquidity,
|
|
7549
|
-
outAmount
|
|
7550
|
-
);
|
|
7551
|
-
}
|
|
8265
|
+
function getFeeInPeriod(cliffFeeNumerator, reductionFactor, passedPeriod) {
|
|
8266
|
+
if (reductionFactor.isZero()) {
|
|
8267
|
+
return cliffFeeNumerator;
|
|
8268
|
+
}
|
|
8269
|
+
const bps = reductionFactor.shln(SCALE_OFFSET).div(new BN6(BASIS_POINT_MAX));
|
|
8270
|
+
const base = ONE_Q64.sub(bps);
|
|
8271
|
+
const result = pow(base, new BN6(passedPeriod));
|
|
8272
|
+
if (result.gt(U128_MAX)) {
|
|
8273
|
+
throw new Error("Math overflow");
|
|
8274
|
+
}
|
|
8275
|
+
const fee = result.mul(cliffFeeNumerator).shrn(SCALE_OFFSET);
|
|
8276
|
+
return fee;
|
|
7552
8277
|
}
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
8278
|
+
function getFeeMode(collectFeeMode, tradeDirection, hasReferral) {
|
|
8279
|
+
let feesOnInput;
|
|
8280
|
+
let feesOnTokenA;
|
|
8281
|
+
if (collectFeeMode === 0 /* BothToken */) {
|
|
8282
|
+
if (tradeDirection === 0 /* AtoB */) {
|
|
8283
|
+
feesOnInput = false;
|
|
8284
|
+
feesOnTokenA = false;
|
|
8285
|
+
} else {
|
|
8286
|
+
feesOnInput = false;
|
|
8287
|
+
feesOnTokenA = true;
|
|
8288
|
+
}
|
|
7560
8289
|
} else {
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
}
|
|
7568
|
-
function getDynamicFeeNumerator(volatilityAccumulator, binStep, variableFeeControl) {
|
|
7569
|
-
if (variableFeeControl.isZero()) {
|
|
7570
|
-
return new BN5(0);
|
|
8290
|
+
if (tradeDirection === 0 /* AtoB */) {
|
|
8291
|
+
feesOnInput = false;
|
|
8292
|
+
feesOnTokenA = false;
|
|
8293
|
+
} else {
|
|
8294
|
+
feesOnInput = true;
|
|
8295
|
+
feesOnTokenA = false;
|
|
8296
|
+
}
|
|
7571
8297
|
}
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
8298
|
+
return {
|
|
8299
|
+
feesOnInput,
|
|
8300
|
+
feesOnTokenA,
|
|
8301
|
+
hasReferral
|
|
8302
|
+
};
|
|
7575
8303
|
}
|
|
7576
|
-
function
|
|
7577
|
-
let
|
|
7578
|
-
if (
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
new
|
|
7583
|
-
new BN5(currentPoint).sub(activationPoint).div(periodFrequency)
|
|
7584
|
-
);
|
|
7585
|
-
feeNumerator = getBaseFeeNumerator(
|
|
7586
|
-
feeSchedulerMode,
|
|
7587
|
-
cliffFeeNumerator,
|
|
7588
|
-
period,
|
|
7589
|
-
reductionFactor
|
|
7590
|
-
);
|
|
7591
|
-
}
|
|
7592
|
-
if (dynamicFeeParams) {
|
|
7593
|
-
const { volatilityAccumulator, binStep, variableFeeControl } = dynamicFeeParams;
|
|
7594
|
-
const dynamicFeeNumberator = getDynamicFeeNumerator(
|
|
7595
|
-
volatilityAccumulator,
|
|
7596
|
-
new BN5(binStep),
|
|
7597
|
-
new BN5(variableFeeControl)
|
|
8304
|
+
function getTotalFeeNumerator(poolFees, baseFeeNumerator, maxFeeNumerator) {
|
|
8305
|
+
let dynamicFeeNumerator = new BN6(0);
|
|
8306
|
+
if (poolFees.dynamicFee.initialized !== 0) {
|
|
8307
|
+
dynamicFeeNumerator = getDynamicFeeNumerator(
|
|
8308
|
+
poolFees.dynamicFee.volatilityAccumulator,
|
|
8309
|
+
new BN6(poolFees.dynamicFee.binStep),
|
|
8310
|
+
new BN6(poolFees.dynamicFee.variableFeeControl)
|
|
7598
8311
|
);
|
|
7599
|
-
feeNumerator = feeNumerator.add(dynamicFeeNumberator);
|
|
7600
8312
|
}
|
|
7601
|
-
|
|
8313
|
+
const totalFeeNumerator = dynamicFeeNumerator.add(baseFeeNumerator);
|
|
8314
|
+
return BN6.min(totalFeeNumerator, maxFeeNumerator);
|
|
7602
8315
|
}
|
|
7603
|
-
function
|
|
7604
|
-
const
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
0 /* Up */
|
|
8316
|
+
function getTotalTradingFeeFromIncludedFeeAmount(poolFees, currentPoint, activationPoint, includedFeeAmount, tradeDirection, maxFeeNumerator) {
|
|
8317
|
+
const baseFeeHandler = getBaseFeeHandler(
|
|
8318
|
+
poolFees.baseFee.cliffFeeNumerator,
|
|
8319
|
+
poolFees.baseFee.firstFactor,
|
|
8320
|
+
poolFees.baseFee.secondFactor,
|
|
8321
|
+
poolFees.baseFee.thirdFactor,
|
|
8322
|
+
poolFees.baseFee.baseFeeMode
|
|
8323
|
+
);
|
|
8324
|
+
const baseFeeNumerator = baseFeeHandler.getBaseFeeNumeratorFromIncludedFeeAmount(
|
|
8325
|
+
currentPoint,
|
|
8326
|
+
activationPoint,
|
|
8327
|
+
tradeDirection,
|
|
8328
|
+
includedFeeAmount
|
|
7617
8329
|
);
|
|
8330
|
+
return getTotalFeeNumerator(poolFees, baseFeeNumerator, maxFeeNumerator);
|
|
7618
8331
|
}
|
|
7619
|
-
function
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
}
|
|
7627
|
-
const nextSqrtPrice = getNextSqrtPrice(
|
|
7628
|
-
actualInAmount,
|
|
7629
|
-
sqrtPrice,
|
|
7630
|
-
liquidity,
|
|
7631
|
-
aToB
|
|
8332
|
+
function getTotalTradingFeeFromExcludedFeeAmount(poolFees, currentPoint, activationPoint, excludedFeeAmount, tradeDirection, maxFeeNumerator) {
|
|
8333
|
+
const baseFeeHandler = getBaseFeeHandler(
|
|
8334
|
+
poolFees.baseFee.cliffFeeNumerator,
|
|
8335
|
+
poolFees.baseFee.firstFactor,
|
|
8336
|
+
poolFees.baseFee.secondFactor,
|
|
8337
|
+
poolFees.baseFee.thirdFactor,
|
|
8338
|
+
poolFees.baseFee.baseFeeMode
|
|
7632
8339
|
);
|
|
7633
|
-
const
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
) : getAmountAFromLiquidityDelta(
|
|
7639
|
-
liquidity,
|
|
7640
|
-
sqrtPrice,
|
|
7641
|
-
nextSqrtPrice,
|
|
7642
|
-
1 /* Down */
|
|
8340
|
+
const baseFeeNumerator = baseFeeHandler.getBaseFeeNumeratorFromExcludedFeeAmount(
|
|
8341
|
+
currentPoint,
|
|
8342
|
+
activationPoint,
|
|
8343
|
+
tradeDirection,
|
|
8344
|
+
excludedFeeAmount
|
|
7643
8345
|
);
|
|
7644
|
-
|
|
7645
|
-
return { amountOut, totalFee, nextSqrtPrice };
|
|
8346
|
+
return getTotalFeeNumerator(poolFees, baseFeeNumerator, maxFeeNumerator);
|
|
7646
8347
|
}
|
|
7647
|
-
function
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
7656
|
-
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7660
|
-
numberOfPeriod: 0,
|
|
7661
|
-
periodFrequency: new BN5(0),
|
|
7662
|
-
reductionFactor: new BN5(0),
|
|
7663
|
-
feeSchedulerMode: 0
|
|
7664
|
-
};
|
|
7665
|
-
}
|
|
7666
|
-
if (numberOfPeriod <= 0) {
|
|
7667
|
-
throw new Error("Total periods must be greater than zero");
|
|
7668
|
-
}
|
|
7669
|
-
if (maxBaseFeeBps > feeNumeratorToBps(new BN5(MAX_FEE_NUMERATOR))) {
|
|
7670
|
-
throw new Error(
|
|
7671
|
-
`maxBaseFeeBps (${maxBaseFeeBps} bps) exceeds maximum allowed value of ${feeNumeratorToBps(
|
|
7672
|
-
new BN5(MAX_FEE_NUMERATOR)
|
|
7673
|
-
)} bps`
|
|
7674
|
-
);
|
|
7675
|
-
}
|
|
7676
|
-
if (minBaseFeeBps > maxBaseFeeBps) {
|
|
7677
|
-
throw new Error(
|
|
7678
|
-
"minBaseFee bps must be less than or equal to maxBaseFee bps"
|
|
7679
|
-
);
|
|
7680
|
-
}
|
|
7681
|
-
if (numberOfPeriod == 0 || totalDuration == 0) {
|
|
7682
|
-
throw new Error(
|
|
7683
|
-
"numberOfPeriod and totalDuration must both greater than zero"
|
|
7684
|
-
);
|
|
7685
|
-
}
|
|
7686
|
-
const maxBaseFeeNumerator = bpsToFeeNumerator(maxBaseFeeBps);
|
|
7687
|
-
const minBaseFeeNumerator = bpsToFeeNumerator(minBaseFeeBps);
|
|
7688
|
-
const periodFrequency = new BN5(totalDuration / numberOfPeriod);
|
|
7689
|
-
let reductionFactor;
|
|
7690
|
-
if (feeSchedulerMode == 0 /* Linear */) {
|
|
7691
|
-
const totalReduction = maxBaseFeeNumerator.sub(minBaseFeeNumerator);
|
|
7692
|
-
reductionFactor = totalReduction.divn(numberOfPeriod);
|
|
7693
|
-
} else {
|
|
7694
|
-
const ratio = minBaseFeeNumerator.toNumber() / maxBaseFeeNumerator.toNumber();
|
|
7695
|
-
const decayBase = Math.pow(ratio, 1 / numberOfPeriod);
|
|
7696
|
-
reductionFactor = new BN5(BASIS_POINT_MAX * (1 - decayBase));
|
|
7697
|
-
}
|
|
8348
|
+
function splitFees(poolFees, feeAmount, hasReferral, hasPartner2) {
|
|
8349
|
+
const protocolFee = feeAmount.muln(poolFees.protocolFeePercent).divn(100);
|
|
8350
|
+
const tradingFee = feeAmount.sub(protocolFee);
|
|
8351
|
+
let referralFee = new BN6(0);
|
|
8352
|
+
if (hasReferral) {
|
|
8353
|
+
referralFee = protocolFee.muln(poolFees.referralFeePercent).divn(100);
|
|
8354
|
+
}
|
|
8355
|
+
const protocolFeeAfterReferral = protocolFee.sub(referralFee);
|
|
8356
|
+
let partnerFee = new BN6(0);
|
|
8357
|
+
if (hasPartner2 && poolFees.partnerFeePercent > 0) {
|
|
8358
|
+
partnerFee = protocolFeeAfterReferral.muln(poolFees.partnerFeePercent).divn(100);
|
|
8359
|
+
}
|
|
8360
|
+
const finalProtocolFee = protocolFeeAfterReferral.sub(partnerFee);
|
|
7698
8361
|
return {
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
feeSchedulerMode
|
|
8362
|
+
tradingFee,
|
|
8363
|
+
protocolFee: finalProtocolFee,
|
|
8364
|
+
referralFee,
|
|
8365
|
+
partnerFee
|
|
7704
8366
|
};
|
|
7705
8367
|
}
|
|
7706
|
-
function
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
|
|
7713
|
-
|
|
7714
|
-
|
|
8368
|
+
function getFeeOnAmount(poolFees, amount, tradeFeeNumerator, hasReferral, hasPartner2) {
|
|
8369
|
+
const { excludedFeeAmount, tradingFee } = getExcludedFeeAmount(
|
|
8370
|
+
tradeFeeNumerator,
|
|
8371
|
+
amount
|
|
8372
|
+
);
|
|
8373
|
+
const splitFeesResult = splitFees(
|
|
8374
|
+
poolFees,
|
|
8375
|
+
tradingFee,
|
|
8376
|
+
hasReferral,
|
|
8377
|
+
hasPartner2
|
|
7715
8378
|
);
|
|
7716
|
-
const deltaBinId = sqrtPriceRatioQ64.sub(ONE).div(BIN_STEP_BPS_U128_DEFAULT).muln(2);
|
|
7717
|
-
const maxVolatilityAccumulator = new BN5(deltaBinId.muln(BASIS_POINT_MAX));
|
|
7718
|
-
const squareVfaBin = maxVolatilityAccumulator.mul(new BN5(BIN_STEP_BPS_DEFAULT)).pow(new BN5(2));
|
|
7719
|
-
const baseFeeNumerator = new BN5(bpsToFeeNumerator(baseFeeBps));
|
|
7720
|
-
const maxDynamicFeeNumerator = baseFeeNumerator.muln(20).divn(100);
|
|
7721
|
-
const vFee = maxDynamicFeeNumerator.mul(new BN5(1e11)).sub(new BN5(99999999999));
|
|
7722
|
-
const variableFeeControl = vFee.div(squareVfaBin);
|
|
7723
8379
|
return {
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
maxVolatilityAccumulator: maxVolatilityAccumulator.toNumber(),
|
|
7730
|
-
variableFeeControl: variableFeeControl.toNumber()
|
|
8380
|
+
amount: excludedFeeAmount,
|
|
8381
|
+
tradingFee: splitFeesResult.tradingFee,
|
|
8382
|
+
protocolFee: splitFeesResult.protocolFee,
|
|
8383
|
+
partnerFee: splitFeesResult.partnerFee,
|
|
8384
|
+
referralFee: splitFeesResult.referralFee
|
|
7731
8385
|
};
|
|
7732
8386
|
}
|
|
7733
8387
|
function getExcludedFeeAmount(tradeFeeNumerator, includedFeeAmount) {
|
|
7734
8388
|
const tradingFee = mulDiv(
|
|
7735
8389
|
includedFeeAmount,
|
|
7736
8390
|
tradeFeeNumerator,
|
|
7737
|
-
new
|
|
8391
|
+
new BN6(FEE_DENOMINATOR),
|
|
7738
8392
|
0 /* Up */
|
|
7739
8393
|
);
|
|
7740
8394
|
const excludedFeeAmount = includedFeeAmount.sub(tradingFee);
|
|
7741
8395
|
return { excludedFeeAmount, tradingFee };
|
|
7742
8396
|
}
|
|
7743
8397
|
function getIncludedFeeAmount(tradeFeeNumerator, excludedFeeAmount) {
|
|
7744
|
-
const denominator = new
|
|
8398
|
+
const denominator = new BN6(FEE_DENOMINATOR).sub(tradeFeeNumerator);
|
|
7745
8399
|
if (denominator.isZero() || denominator.isNeg()) {
|
|
7746
8400
|
throw new Error("Invalid fee numerator");
|
|
7747
8401
|
}
|
|
7748
8402
|
const includedFeeAmount = mulDiv(
|
|
7749
8403
|
excludedFeeAmount,
|
|
7750
|
-
new
|
|
8404
|
+
new BN6(FEE_DENOMINATOR),
|
|
7751
8405
|
denominator,
|
|
7752
8406
|
0 /* Up */
|
|
7753
8407
|
);
|
|
7754
|
-
const
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
|
|
8408
|
+
const feeAmount = includedFeeAmount.sub(excludedFeeAmount);
|
|
8409
|
+
return { includedFeeAmount, feeAmount };
|
|
8410
|
+
}
|
|
8411
|
+
function getMaxFeeNumerator(poolVersion) {
|
|
8412
|
+
switch (poolVersion) {
|
|
8413
|
+
case 0 /* V0 */:
|
|
8414
|
+
return new BN6(MAX_FEE_NUMERATOR_V0);
|
|
8415
|
+
case 1 /* V1 */:
|
|
8416
|
+
return new BN6(MAX_FEE_NUMERATOR_V1);
|
|
8417
|
+
default:
|
|
8418
|
+
throw new Error("Invalid pool version");
|
|
7760
8419
|
}
|
|
7761
|
-
return includedFeeAmount;
|
|
7762
8420
|
}
|
|
7763
|
-
function
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
throw new Error("Price range is violated");
|
|
8421
|
+
function getMaxFeeBps(poolVersion) {
|
|
8422
|
+
switch (poolVersion) {
|
|
8423
|
+
case 0 /* V0 */:
|
|
8424
|
+
return MAX_FEE_BPS_V0;
|
|
8425
|
+
case 1 /* V1 */:
|
|
8426
|
+
return MAX_FEE_BPS_V1;
|
|
8427
|
+
default:
|
|
8428
|
+
throw new Error("Invalid pool version");
|
|
7772
8429
|
}
|
|
7773
|
-
|
|
7774
|
-
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
8430
|
+
}
|
|
8431
|
+
|
|
8432
|
+
// src/math/poolFees/rateLimiter.ts
|
|
8433
|
+
function isZeroRateLimiter(referenceAmount, maxLimiterDuration, maxFeeBps, feeIncrementBps) {
|
|
8434
|
+
return referenceAmount.isZero() && maxLimiterDuration === 0 && maxFeeBps === 0 && feeIncrementBps === 0;
|
|
8435
|
+
}
|
|
8436
|
+
function isNonZeroRateLimiter(referenceAmount, maxLimiterDuration, maxFeeBps, feeIncrementBps) {
|
|
8437
|
+
return referenceAmount.isZero() && maxLimiterDuration !== 0 && maxFeeBps !== 0 && feeIncrementBps !== 0;
|
|
8438
|
+
}
|
|
8439
|
+
function isRateLimiterApplied(referenceAmount, maxLimiterDuration, maxFeeBps, feeIncrementBps, currentPoint, activationPoint, tradeDirection) {
|
|
8440
|
+
if (isZeroRateLimiter(
|
|
8441
|
+
referenceAmount,
|
|
8442
|
+
maxLimiterDuration,
|
|
8443
|
+
maxFeeBps,
|
|
8444
|
+
feeIncrementBps
|
|
8445
|
+
)) {
|
|
8446
|
+
return false;
|
|
8447
|
+
}
|
|
8448
|
+
if (tradeDirection === 0 /* AtoB */) {
|
|
8449
|
+
return false;
|
|
8450
|
+
}
|
|
8451
|
+
if (currentPoint.lt(activationPoint)) {
|
|
8452
|
+
return false;
|
|
8453
|
+
}
|
|
8454
|
+
const lastEffectiveRateLimiterPoint = activationPoint.add(
|
|
8455
|
+
new BN7(maxLimiterDuration)
|
|
7778
8456
|
);
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
8457
|
+
if (currentPoint.gt(lastEffectiveRateLimiterPoint)) {
|
|
8458
|
+
return false;
|
|
8459
|
+
}
|
|
8460
|
+
return true;
|
|
7783
8461
|
}
|
|
7784
|
-
function
|
|
7785
|
-
const
|
|
7786
|
-
|
|
7787
|
-
|
|
7788
|
-
outAmount,
|
|
7789
|
-
false
|
|
8462
|
+
function getMaxIndex(maxFeeBps, cliffFeeNumerator, feeIncrementBps) {
|
|
8463
|
+
const maxFeeNumerator = toNumerator(
|
|
8464
|
+
new BN7(maxFeeBps),
|
|
8465
|
+
new BN7(FEE_DENOMINATOR)
|
|
7790
8466
|
);
|
|
7791
|
-
if (
|
|
7792
|
-
throw new Error("
|
|
8467
|
+
if (cliffFeeNumerator.gt(maxFeeNumerator)) {
|
|
8468
|
+
throw new Error("cliffFeeNumerator cannot be greater than maxFeeNumerator");
|
|
7793
8469
|
}
|
|
7794
|
-
const
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
0 /* Up */
|
|
8470
|
+
const deltaNumerator = maxFeeNumerator.sub(cliffFeeNumerator);
|
|
8471
|
+
const feeIncrementNumerator = toNumerator(
|
|
8472
|
+
new BN7(feeIncrementBps),
|
|
8473
|
+
new BN7(FEE_DENOMINATOR)
|
|
7799
8474
|
);
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
|
|
8475
|
+
if (feeIncrementNumerator.isZero()) {
|
|
8476
|
+
throw new Error("feeIncrementNumerator cannot be zero");
|
|
8477
|
+
}
|
|
8478
|
+
const maxIndex = deltaNumerator.div(feeIncrementNumerator);
|
|
8479
|
+
return maxIndex;
|
|
7804
8480
|
}
|
|
7805
|
-
function
|
|
7806
|
-
|
|
7807
|
-
|
|
7808
|
-
let actualPartnerFee = new BN5(0);
|
|
7809
|
-
let actualReferralFee = new BN5(0);
|
|
7810
|
-
const tradeFeeNumerator = getFeeNumerator(
|
|
7811
|
-
currentPoint,
|
|
7812
|
-
pool.activationPoint,
|
|
7813
|
-
pool.poolFees.baseFee.numberOfPeriod,
|
|
7814
|
-
pool.poolFees.baseFee.periodFrequency,
|
|
7815
|
-
pool.poolFees.baseFee.feeSchedulerMode,
|
|
7816
|
-
pool.poolFees.baseFee.cliffFeeNumerator,
|
|
7817
|
-
pool.poolFees.baseFee.reductionFactor,
|
|
7818
|
-
pool.poolFees.dynamicFee.initialized === 1 ? {
|
|
7819
|
-
volatilityAccumulator: pool.poolFees.dynamicFee.volatilityAccumulator,
|
|
7820
|
-
binStep: pool.poolFees.dynamicFee.binStep,
|
|
7821
|
-
variableFeeControl: pool.poolFees.dynamicFee.variableFeeControl
|
|
7822
|
-
} : void 0
|
|
7823
|
-
);
|
|
7824
|
-
let includedFeeOutAmount;
|
|
7825
|
-
if (feeMode.feeOnInput) {
|
|
7826
|
-
includedFeeOutAmount = outAmount;
|
|
8481
|
+
function getFeeNumeratorFromIncludedFeeAmount(inputAmount, referenceAmount, cliffFeeNumerator, maxFeeBps, feeIncrementBps) {
|
|
8482
|
+
if (inputAmount.lte(referenceAmount)) {
|
|
8483
|
+
return cliffFeeNumerator;
|
|
7827
8484
|
} else {
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
totalFee,
|
|
7832
|
-
new BN5(pool.poolFees.protocolFeePercent),
|
|
7833
|
-
new BN5(100),
|
|
7834
|
-
1 /* Down */
|
|
8485
|
+
const maxFeeNumerator = toNumerator(
|
|
8486
|
+
new BN7(maxFeeBps),
|
|
8487
|
+
new BN7(FEE_DENOMINATOR)
|
|
7835
8488
|
);
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
7842
|
-
|
|
8489
|
+
const c = cliffFeeNumerator;
|
|
8490
|
+
const inputMinusRef = inputAmount.sub(referenceAmount);
|
|
8491
|
+
const a = inputMinusRef.div(referenceAmount);
|
|
8492
|
+
const b = inputMinusRef.mod(referenceAmount);
|
|
8493
|
+
const maxIndex = getMaxIndex(maxFeeBps, cliffFeeNumerator, feeIncrementBps);
|
|
8494
|
+
const i = toNumerator(new BN7(feeIncrementBps), new BN7(FEE_DENOMINATOR));
|
|
8495
|
+
const x0 = referenceAmount;
|
|
8496
|
+
const one = new BN7(1);
|
|
8497
|
+
const two = new BN7(2);
|
|
8498
|
+
let tradingFeeNumerator;
|
|
8499
|
+
if (a.lt(maxIndex)) {
|
|
8500
|
+
const numerator1 = c.add(c.mul(a)).add(i.mul(a).mul(a.add(one)).div(two));
|
|
8501
|
+
const numerator2 = c.add(i.mul(a.add(one)));
|
|
8502
|
+
const firstFee = x0.mul(numerator1);
|
|
8503
|
+
const secondFee = b.mul(numerator2);
|
|
8504
|
+
tradingFeeNumerator = firstFee.add(secondFee);
|
|
8505
|
+
} else {
|
|
8506
|
+
const numerator1 = c.add(c.mul(maxIndex)).add(i.mul(maxIndex).mul(maxIndex.add(one)).div(two));
|
|
8507
|
+
const numerator2 = maxFeeNumerator;
|
|
8508
|
+
const firstFee = x0.mul(numerator1);
|
|
8509
|
+
const d = a.sub(maxIndex);
|
|
8510
|
+
const leftAmount = d.mul(x0).add(b);
|
|
8511
|
+
const secondFee = leftAmount.mul(numerator2);
|
|
8512
|
+
tradingFeeNumerator = firstFee.add(secondFee);
|
|
7843
8513
|
}
|
|
7844
|
-
const
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
new
|
|
7849
|
-
|
|
8514
|
+
const denominator = new BN7(FEE_DENOMINATOR);
|
|
8515
|
+
const tradingFee = tradingFeeNumerator.add(denominator).sub(one).div(denominator);
|
|
8516
|
+
const numerator = mulDiv(tradingFee, denominator, inputAmount, 0 /* Up */);
|
|
8517
|
+
if (numerator.gt(new BN7(U64_MAX))) {
|
|
8518
|
+
throw new Error("Numerator does not fit in u64");
|
|
8519
|
+
}
|
|
8520
|
+
return numerator;
|
|
8521
|
+
}
|
|
8522
|
+
}
|
|
8523
|
+
function getExcludedFeeAmountFromIncludedFeeAmount(includedFeeAmount, referenceAmount, cliffFeeNumerator, maxFeeBps, feeIncrementBps) {
|
|
8524
|
+
const feeNumerator = getFeeNumeratorFromIncludedFeeAmount(
|
|
8525
|
+
includedFeeAmount,
|
|
8526
|
+
referenceAmount,
|
|
8527
|
+
cliffFeeNumerator,
|
|
8528
|
+
maxFeeBps,
|
|
8529
|
+
feeIncrementBps
|
|
8530
|
+
);
|
|
8531
|
+
const { excludedFeeAmount } = getExcludedFeeAmount(
|
|
8532
|
+
feeNumerator,
|
|
8533
|
+
includedFeeAmount
|
|
8534
|
+
);
|
|
8535
|
+
return excludedFeeAmount;
|
|
8536
|
+
}
|
|
8537
|
+
function getCheckedAmounts(referenceAmount, cliffFeeNumerator, maxFeeBps, feeIncrementBps) {
|
|
8538
|
+
const maxIndex = getMaxIndex(maxFeeBps, cliffFeeNumerator, feeIncrementBps);
|
|
8539
|
+
const x0 = referenceAmount;
|
|
8540
|
+
const one = new BN7(1);
|
|
8541
|
+
const maxIndexInputAmount = maxIndex.add(one).mul(x0);
|
|
8542
|
+
if (maxIndexInputAmount.lte(U64_MAX)) {
|
|
8543
|
+
const checkedIncludedFeeAmount = maxIndexInputAmount;
|
|
8544
|
+
const checkedExcludedFeeAmount = getExcludedFeeAmountFromIncludedFeeAmount(
|
|
8545
|
+
checkedIncludedFeeAmount,
|
|
8546
|
+
referenceAmount,
|
|
8547
|
+
cliffFeeNumerator,
|
|
8548
|
+
maxFeeBps,
|
|
8549
|
+
feeIncrementBps
|
|
8550
|
+
);
|
|
8551
|
+
return {
|
|
8552
|
+
checkedExcludedFeeAmount,
|
|
8553
|
+
checkedIncludedFeeAmount,
|
|
8554
|
+
isOverflow: false
|
|
8555
|
+
};
|
|
8556
|
+
} else {
|
|
8557
|
+
const checkedIncludedFeeAmount = U64_MAX;
|
|
8558
|
+
const checkedExcludedFeeAmount = getExcludedFeeAmountFromIncludedFeeAmount(
|
|
8559
|
+
checkedIncludedFeeAmount,
|
|
8560
|
+
referenceAmount,
|
|
8561
|
+
cliffFeeNumerator,
|
|
8562
|
+
maxFeeBps,
|
|
8563
|
+
feeIncrementBps
|
|
7850
8564
|
);
|
|
7851
|
-
|
|
8565
|
+
return {
|
|
8566
|
+
checkedExcludedFeeAmount,
|
|
8567
|
+
checkedIncludedFeeAmount,
|
|
8568
|
+
isOverflow: true
|
|
8569
|
+
};
|
|
7852
8570
|
}
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
8571
|
+
}
|
|
8572
|
+
function getFeeNumeratorFromExcludedFeeAmount(excludedFeeAmount, referenceAmount, cliffFeeNumerator, maxFeeBps, feeIncrementBps) {
|
|
8573
|
+
const excludedFeeReferenceAmount = getExcludedFeeAmountFromIncludedFeeAmount(
|
|
8574
|
+
referenceAmount,
|
|
8575
|
+
referenceAmount,
|
|
8576
|
+
cliffFeeNumerator,
|
|
8577
|
+
maxFeeBps,
|
|
8578
|
+
feeIncrementBps
|
|
8579
|
+
);
|
|
8580
|
+
if (excludedFeeAmount.lte(excludedFeeReferenceAmount)) {
|
|
8581
|
+
return cliffFeeNumerator;
|
|
8582
|
+
}
|
|
8583
|
+
const { checkedExcludedFeeAmount, checkedIncludedFeeAmount, isOverflow } = getCheckedAmounts(
|
|
8584
|
+
referenceAmount,
|
|
8585
|
+
cliffFeeNumerator,
|
|
8586
|
+
maxFeeBps,
|
|
8587
|
+
feeIncrementBps
|
|
8588
|
+
);
|
|
8589
|
+
if (excludedFeeAmount.eq(checkedExcludedFeeAmount)) {
|
|
8590
|
+
return getFeeNumeratorFromIncludedFeeAmount(
|
|
8591
|
+
checkedIncludedFeeAmount,
|
|
8592
|
+
referenceAmount,
|
|
8593
|
+
cliffFeeNumerator,
|
|
8594
|
+
maxFeeBps,
|
|
8595
|
+
feeIncrementBps
|
|
7859
8596
|
);
|
|
7860
|
-
|
|
7861
|
-
|
|
7862
|
-
|
|
8597
|
+
}
|
|
8598
|
+
let includedFeeAmount;
|
|
8599
|
+
if (excludedFeeAmount.lt(checkedExcludedFeeAmount)) {
|
|
8600
|
+
const TWO = new BN7(2);
|
|
8601
|
+
const FOUR = new BN7(4);
|
|
8602
|
+
const i = toNumerator(new BN7(feeIncrementBps), new BN7(FEE_DENOMINATOR));
|
|
8603
|
+
const x0 = referenceAmount;
|
|
8604
|
+
const d = new BN7(FEE_DENOMINATOR);
|
|
8605
|
+
const c = cliffFeeNumerator;
|
|
8606
|
+
const ex = excludedFeeAmount;
|
|
8607
|
+
const x = i;
|
|
8608
|
+
const y = TWO.mul(d).mul(x0).add(i.mul(x0)).sub(TWO.mul(c).mul(x0));
|
|
8609
|
+
const z = TWO.mul(ex).mul(d).mul(x0);
|
|
8610
|
+
const discriminant = y.mul(y).sub(FOUR.mul(x).mul(z));
|
|
8611
|
+
const sqrtDiscriminant = sqrt(discriminant);
|
|
8612
|
+
includedFeeAmount = y.sub(sqrtDiscriminant).div(TWO.mul(x));
|
|
8613
|
+
const numerator = y.sub(sqrtDiscriminant);
|
|
8614
|
+
const denominator = TWO.mul(x);
|
|
8615
|
+
includedFeeAmount = numerator.div(denominator);
|
|
8616
|
+
const aPlusOne = includedFeeAmount.div(x0);
|
|
8617
|
+
const firstExcludedFeeAmount = getExcludedFeeAmountFromIncludedFeeAmount(
|
|
8618
|
+
includedFeeAmount,
|
|
8619
|
+
referenceAmount,
|
|
8620
|
+
cliffFeeNumerator,
|
|
8621
|
+
maxFeeBps,
|
|
8622
|
+
feeIncrementBps
|
|
7863
8623
|
);
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
new BN5(pool.poolFees.protocolFeePercent),
|
|
7867
|
-
new BN5(100),
|
|
7868
|
-
1 /* Down */
|
|
8624
|
+
const excludedFeeRemainingAmount = excludedFeeAmount.sub(
|
|
8625
|
+
firstExcludedFeeAmount
|
|
7869
8626
|
);
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
new BN5(100),
|
|
7875
|
-
1 /* Down */
|
|
7876
|
-
);
|
|
7877
|
-
}
|
|
7878
|
-
const protocolFeeAfterReferral = actualProtocolFee.sub(actualReferralFee);
|
|
7879
|
-
actualPartnerFee = mulDiv(
|
|
7880
|
-
protocolFeeAfterReferral,
|
|
7881
|
-
new BN5(pool.poolFees.partnerFeePercent),
|
|
7882
|
-
new BN5(100),
|
|
7883
|
-
1 /* Down */
|
|
8627
|
+
const remainingAmountFeeNumerator = c.add(i.mul(aPlusOne));
|
|
8628
|
+
const { includedFeeAmount: includedFeeRemainingAmount } = getIncludedFeeAmount(
|
|
8629
|
+
remainingAmountFeeNumerator,
|
|
8630
|
+
excludedFeeRemainingAmount
|
|
7884
8631
|
);
|
|
7885
|
-
|
|
8632
|
+
includedFeeAmount = includedFeeAmount.add(includedFeeRemainingAmount);
|
|
7886
8633
|
} else {
|
|
7887
|
-
|
|
8634
|
+
if (isOverflow) {
|
|
8635
|
+
throw new Error("Math overflow in getFeeNumeratorFromExcludedFeeAmount");
|
|
8636
|
+
}
|
|
8637
|
+
const excludedFeeRemainingAmount = excludedFeeAmount.sub(
|
|
8638
|
+
checkedExcludedFeeAmount
|
|
8639
|
+
);
|
|
8640
|
+
const maxFeeNumerator = toNumerator(
|
|
8641
|
+
new BN7(maxFeeBps),
|
|
8642
|
+
new BN7(FEE_DENOMINATOR)
|
|
8643
|
+
);
|
|
8644
|
+
const { includedFeeAmount: includedFeeRemainingAmount } = getIncludedFeeAmount(maxFeeNumerator, excludedFeeRemainingAmount);
|
|
8645
|
+
includedFeeAmount = includedFeeRemainingAmount.add(
|
|
8646
|
+
checkedIncludedFeeAmount
|
|
8647
|
+
);
|
|
7888
8648
|
}
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
8649
|
+
const tradingFee = includedFeeAmount.sub(excludedFeeAmount);
|
|
8650
|
+
const feeNumerator = mulDiv(
|
|
8651
|
+
tradingFee,
|
|
8652
|
+
new BN7(FEE_DENOMINATOR),
|
|
8653
|
+
includedFeeAmount,
|
|
8654
|
+
0 /* Up */
|
|
8655
|
+
);
|
|
8656
|
+
if (feeNumerator.lt(cliffFeeNumerator)) {
|
|
8657
|
+
throw new Error("feeNumerator is less than cliffFeeNumerator");
|
|
8658
|
+
}
|
|
8659
|
+
return feeNumerator;
|
|
7900
8660
|
}
|
|
7901
8661
|
|
|
7902
|
-
// src/
|
|
7903
|
-
import
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
// and get the real compute units used
|
|
7915
|
-
ComputeBudgetProgram.setComputeUnitLimit({ units: 14e5 }),
|
|
7916
|
-
...instructions
|
|
7917
|
-
];
|
|
7918
|
-
const testTransaction = new VersionedTransaction(
|
|
7919
|
-
new TransactionMessage({
|
|
7920
|
-
instructions: testInstructions,
|
|
7921
|
-
payerKey: payer,
|
|
7922
|
-
// RecentBlockhash can by any public key during simulation
|
|
7923
|
-
// since 'replaceRecentBlockhash' is set to 'true' below
|
|
7924
|
-
recentBlockhash: PublicKey4.default.toString()
|
|
7925
|
-
}).compileToV0Message(lookupTables)
|
|
8662
|
+
// src/math/poolFees/feeScheduler.ts
|
|
8663
|
+
import BN8 from "bn.js";
|
|
8664
|
+
function getMaxBaseFeeNumerator(cliffFeeNumerator) {
|
|
8665
|
+
return cliffFeeNumerator;
|
|
8666
|
+
}
|
|
8667
|
+
function getMinBaseFeeNumerator(cliffFeeNumerator, numberOfPeriod, periodFrequency, reductionFactor, feeSchedulerMode) {
|
|
8668
|
+
return getBaseFeeNumeratorByPeriod(
|
|
8669
|
+
cliffFeeNumerator,
|
|
8670
|
+
numberOfPeriod,
|
|
8671
|
+
periodFrequency,
|
|
8672
|
+
reductionFactor,
|
|
8673
|
+
feeSchedulerMode
|
|
7926
8674
|
);
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
8675
|
+
}
|
|
8676
|
+
function getBaseFeeNumeratorByPeriod(cliffFeeNumerator, numberOfPeriod, period, reductionFactor, feeSchedulerMode) {
|
|
8677
|
+
const periodValue = BN8.min(period, new BN8(numberOfPeriod));
|
|
8678
|
+
const periodNumber = periodValue.toNumber();
|
|
8679
|
+
if (periodNumber > U16_MAX) {
|
|
8680
|
+
throw new Error("Math overflow");
|
|
8681
|
+
}
|
|
8682
|
+
switch (feeSchedulerMode) {
|
|
8683
|
+
case 0 /* FeeSchedulerLinear */: {
|
|
8684
|
+
const feeNumerator = getFeeNumeratorOnLinearFeeScheduler(
|
|
8685
|
+
cliffFeeNumerator,
|
|
8686
|
+
reductionFactor,
|
|
8687
|
+
periodNumber
|
|
8688
|
+
);
|
|
8689
|
+
return feeNumerator;
|
|
8690
|
+
}
|
|
8691
|
+
case 1 /* FeeSchedulerExponential */: {
|
|
8692
|
+
const feeNumerator = getFeeNumeratorOnExponentialFeeScheduler(
|
|
8693
|
+
cliffFeeNumerator,
|
|
8694
|
+
reductionFactor,
|
|
8695
|
+
periodNumber
|
|
8696
|
+
);
|
|
8697
|
+
return feeNumerator;
|
|
8698
|
+
}
|
|
8699
|
+
default:
|
|
8700
|
+
throw new Error("Invalid fee scheduler mode");
|
|
7938
8701
|
}
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
8702
|
+
}
|
|
8703
|
+
function getFeeNumeratorOnLinearFeeScheduler(cliffFeeNumerator, reductionFactor, period) {
|
|
8704
|
+
const reduction = new BN8(period).mul(reductionFactor);
|
|
8705
|
+
return cliffFeeNumerator.sub(reduction);
|
|
8706
|
+
}
|
|
8707
|
+
function getFeeNumeratorOnExponentialFeeScheduler(cliffFeeNumerator, reductionFactor, period) {
|
|
8708
|
+
if (period === 0) {
|
|
8709
|
+
return cliffFeeNumerator;
|
|
8710
|
+
}
|
|
8711
|
+
const basisPointMax = new BN8(BASIS_POINT_MAX);
|
|
8712
|
+
const bps = new BN8(reductionFactor).shln(64).div(basisPointMax);
|
|
8713
|
+
const base = ONE_Q64.sub(bps);
|
|
8714
|
+
const result = pow(base, new BN8(period));
|
|
8715
|
+
return cliffFeeNumerator.mul(result).div(ONE_Q64);
|
|
8716
|
+
}
|
|
8717
|
+
function getBaseFeeNumerator(cliffFeeNumerator, numberOfPeriod, periodFrequency, reductionFactor, feeSchedulerMode, currentPoint, activationPoint) {
|
|
8718
|
+
if (periodFrequency.isZero()) {
|
|
8719
|
+
return cliffFeeNumerator;
|
|
7944
8720
|
}
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
|
|
8721
|
+
const period = currentPoint.sub(activationPoint).div(periodFrequency);
|
|
8722
|
+
return getBaseFeeNumeratorByPeriod(
|
|
8723
|
+
cliffFeeNumerator,
|
|
8724
|
+
numberOfPeriod,
|
|
8725
|
+
period,
|
|
8726
|
+
reductionFactor,
|
|
8727
|
+
feeSchedulerMode
|
|
7952
8728
|
);
|
|
7953
|
-
|
|
7954
|
-
|
|
8729
|
+
}
|
|
8730
|
+
|
|
8731
|
+
// src/math/poolFees/baseFee.ts
|
|
8732
|
+
var FeeRateLimiter = class {
|
|
8733
|
+
constructor(cliffFeeNumerator, feeIncrementBps, maxFeeBps, maxLimiterDuration, referenceAmount) {
|
|
8734
|
+
this.cliffFeeNumerator = cliffFeeNumerator;
|
|
8735
|
+
this.feeIncrementBps = feeIncrementBps;
|
|
8736
|
+
this.maxFeeBps = maxFeeBps;
|
|
8737
|
+
this.maxLimiterDuration = maxLimiterDuration;
|
|
8738
|
+
this.referenceAmount = referenceAmount;
|
|
8739
|
+
}
|
|
8740
|
+
validate(collectFeeMode, activationType, poolVersion) {
|
|
8741
|
+
return validateFeeRateLimiter(
|
|
8742
|
+
this.cliffFeeNumerator,
|
|
8743
|
+
this.feeIncrementBps,
|
|
8744
|
+
this.maxFeeBps,
|
|
8745
|
+
this.maxLimiterDuration,
|
|
8746
|
+
this.referenceAmount,
|
|
8747
|
+
collectFeeMode,
|
|
8748
|
+
activationType,
|
|
8749
|
+
poolVersion
|
|
8750
|
+
);
|
|
7955
8751
|
}
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
8752
|
+
getBaseFeeNumeratorFromIncludedFeeAmount(currentPoint, activationPoint, tradeDirection, includedFeeAmount) {
|
|
8753
|
+
if (isRateLimiterApplied(
|
|
8754
|
+
this.referenceAmount,
|
|
8755
|
+
this.maxLimiterDuration,
|
|
8756
|
+
this.maxFeeBps,
|
|
8757
|
+
this.feeIncrementBps,
|
|
8758
|
+
currentPoint,
|
|
8759
|
+
activationPoint,
|
|
8760
|
+
tradeDirection
|
|
8761
|
+
)) {
|
|
8762
|
+
return getFeeNumeratorFromIncludedFeeAmount(
|
|
8763
|
+
includedFeeAmount,
|
|
8764
|
+
this.referenceAmount,
|
|
8765
|
+
this.cliffFeeNumerator,
|
|
8766
|
+
this.maxFeeBps,
|
|
8767
|
+
this.feeIncrementBps
|
|
8768
|
+
);
|
|
8769
|
+
} else {
|
|
8770
|
+
return this.cliffFeeNumerator;
|
|
8771
|
+
}
|
|
8772
|
+
}
|
|
8773
|
+
getBaseFeeNumeratorFromExcludedFeeAmount(currentPoint, activationPoint, tradeDirection, excludedFeeAmount) {
|
|
8774
|
+
if (isRateLimiterApplied(
|
|
8775
|
+
this.referenceAmount,
|
|
8776
|
+
this.maxLimiterDuration,
|
|
8777
|
+
this.maxFeeBps,
|
|
8778
|
+
this.feeIncrementBps,
|
|
8779
|
+
currentPoint,
|
|
8780
|
+
activationPoint,
|
|
8781
|
+
tradeDirection
|
|
8782
|
+
)) {
|
|
8783
|
+
return getFeeNumeratorFromExcludedFeeAmount(
|
|
8784
|
+
excludedFeeAmount,
|
|
8785
|
+
this.referenceAmount,
|
|
8786
|
+
this.cliffFeeNumerator,
|
|
8787
|
+
this.maxFeeBps,
|
|
8788
|
+
this.feeIncrementBps
|
|
8789
|
+
);
|
|
8790
|
+
} else {
|
|
8791
|
+
return this.cliffFeeNumerator;
|
|
8792
|
+
}
|
|
7961
8793
|
}
|
|
7962
|
-
return estimatedComputeUnitUsage + extraComputeUnitBuffer;
|
|
7963
|
-
});
|
|
7964
|
-
var getEstimatedComputeUnitIxWithBuffer = (connection, instructions, feePayer, buffer) => __async(void 0, null, function* () {
|
|
7965
|
-
const units = yield getEstimatedComputeUnitUsageWithBuffer(
|
|
7966
|
-
connection,
|
|
7967
|
-
instructions,
|
|
7968
|
-
feePayer,
|
|
7969
|
-
buffer
|
|
7970
|
-
).catch((error) => {
|
|
7971
|
-
console.error("Error::getEstimatedComputeUnitUsageWithBuffer", error);
|
|
7972
|
-
return 14e5;
|
|
7973
|
-
});
|
|
7974
|
-
return ComputeBudgetProgram.setComputeUnitLimit({ units });
|
|
7975
|
-
});
|
|
7976
|
-
|
|
7977
|
-
// src/helpers/utils.ts
|
|
7978
|
-
import { BN as BN6 } from "@coral-xyz/anchor";
|
|
7979
|
-
import Decimal3 from "decimal.js";
|
|
7980
|
-
var getMaxAmountWithSlippage = (amount, rate) => {
|
|
7981
|
-
const slippage = (100 + rate) / 100 * BASIS_POINT_MAX;
|
|
7982
|
-
return amount.mul(new BN6(slippage)).div(new BN6(BASIS_POINT_MAX));
|
|
7983
8794
|
};
|
|
7984
|
-
var
|
|
7985
|
-
|
|
7986
|
-
|
|
8795
|
+
var FeeScheduler = class {
|
|
8796
|
+
constructor(cliffFeeNumerator, numberOfPeriod, periodFrequency, reductionFactor, feeSchedulerMode) {
|
|
8797
|
+
this.cliffFeeNumerator = cliffFeeNumerator;
|
|
8798
|
+
this.numberOfPeriod = numberOfPeriod;
|
|
8799
|
+
this.periodFrequency = periodFrequency;
|
|
8800
|
+
this.reductionFactor = reductionFactor;
|
|
8801
|
+
this.feeSchedulerMode = feeSchedulerMode;
|
|
8802
|
+
}
|
|
8803
|
+
validate(collectFeeMode, activationType, poolVersion) {
|
|
8804
|
+
return validateFeeScheduler(
|
|
8805
|
+
this.numberOfPeriod,
|
|
8806
|
+
this.periodFrequency,
|
|
8807
|
+
this.reductionFactor,
|
|
8808
|
+
this.cliffFeeNumerator,
|
|
8809
|
+
this.feeSchedulerMode,
|
|
8810
|
+
poolVersion
|
|
8811
|
+
);
|
|
8812
|
+
}
|
|
8813
|
+
getBaseFeeNumeratorFromIncludedFeeAmount(currentPoint, activationPoint) {
|
|
8814
|
+
return getBaseFeeNumerator(
|
|
8815
|
+
this.cliffFeeNumerator,
|
|
8816
|
+
this.numberOfPeriod,
|
|
8817
|
+
this.periodFrequency,
|
|
8818
|
+
this.reductionFactor,
|
|
8819
|
+
this.feeSchedulerMode,
|
|
8820
|
+
currentPoint,
|
|
8821
|
+
activationPoint
|
|
8822
|
+
);
|
|
8823
|
+
}
|
|
8824
|
+
getBaseFeeNumeratorFromExcludedFeeAmount(currentPoint, activationPoint) {
|
|
8825
|
+
return getBaseFeeNumerator(
|
|
8826
|
+
this.cliffFeeNumerator,
|
|
8827
|
+
this.numberOfPeriod,
|
|
8828
|
+
this.periodFrequency,
|
|
8829
|
+
this.reductionFactor,
|
|
8830
|
+
this.feeSchedulerMode,
|
|
8831
|
+
currentPoint,
|
|
8832
|
+
activationPoint
|
|
8833
|
+
);
|
|
8834
|
+
}
|
|
7987
8835
|
};
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
8836
|
+
function getBaseFeeHandler(cliffFeeNumerator, firstFactor, secondFactor, thirdFactor, baseFeeMode) {
|
|
8837
|
+
switch (baseFeeMode) {
|
|
8838
|
+
case 0 /* FeeSchedulerLinear */:
|
|
8839
|
+
case 1 /* FeeSchedulerExponential */: {
|
|
8840
|
+
if (secondFactor.length < 8) {
|
|
8841
|
+
throw new Error(
|
|
8842
|
+
"TypeCastFailed: secondFactor must be at least 8 bytes"
|
|
8843
|
+
);
|
|
8844
|
+
}
|
|
8845
|
+
const periodFrequency = new BN9(
|
|
8846
|
+
Buffer.from(secondFactor.slice(0, 8)),
|
|
8847
|
+
"le"
|
|
8848
|
+
);
|
|
8849
|
+
const feeScheduler = new FeeScheduler(
|
|
8850
|
+
cliffFeeNumerator,
|
|
8851
|
+
firstFactor,
|
|
8852
|
+
periodFrequency,
|
|
8853
|
+
thirdFactor,
|
|
8854
|
+
baseFeeMode
|
|
8855
|
+
);
|
|
8856
|
+
return feeScheduler;
|
|
8857
|
+
}
|
|
8858
|
+
case 2 /* RateLimiter */: {
|
|
8859
|
+
if (secondFactor.length < 8) {
|
|
8860
|
+
throw new Error(
|
|
8861
|
+
"TypeCastFailed: secondFactor must be at least 8 bytes"
|
|
8862
|
+
);
|
|
8863
|
+
}
|
|
8864
|
+
const maxLimiterDuration = Buffer.from(
|
|
8865
|
+
secondFactor.slice(0, 4)
|
|
8866
|
+
).readUInt32LE(0);
|
|
8867
|
+
const maxFeeBps = Buffer.from(secondFactor.slice(4, 8)).readUInt32LE(0);
|
|
8868
|
+
const feeRateLimiter = new FeeRateLimiter(
|
|
8869
|
+
cliffFeeNumerator,
|
|
8870
|
+
firstFactor,
|
|
8871
|
+
maxLimiterDuration,
|
|
8872
|
+
maxFeeBps,
|
|
8873
|
+
thirdFactor
|
|
8874
|
+
);
|
|
8875
|
+
return feeRateLimiter;
|
|
8876
|
+
}
|
|
8877
|
+
default:
|
|
8878
|
+
throw new Error("Invalid base fee mode");
|
|
7991
8879
|
}
|
|
7992
|
-
|
|
7993
|
-
|
|
8880
|
+
}
|
|
8881
|
+
|
|
8882
|
+
// src/math/poolFees/dynamicFee.ts
|
|
8883
|
+
import BN10 from "bn.js";
|
|
8884
|
+
function isDynamicFeeEnabled(dynamicFee) {
|
|
8885
|
+
return dynamicFee.initialized !== 0;
|
|
8886
|
+
}
|
|
8887
|
+
function getDynamicFeeNumerator(volatilityAccumulator, binStep, variableFeeControl) {
|
|
8888
|
+
const squareVfaBin = volatilityAccumulator.mul(new BN10(binStep)).pow(new BN10(2));
|
|
8889
|
+
const vFee = variableFeeControl.mul(squareVfaBin);
|
|
8890
|
+
return vFee.add(new BN10(DYNAMIC_FEE_ROUNDING_OFFSET)).div(new BN10(DYNAMIC_FEE_SCALING_FACTOR));
|
|
8891
|
+
}
|
|
8892
|
+
|
|
8893
|
+
// src/math/quote.ts
|
|
8894
|
+
import BN12 from "bn.js";
|
|
8895
|
+
|
|
8896
|
+
// src/math/curve.ts
|
|
8897
|
+
import BN11 from "bn.js";
|
|
8898
|
+
function getNextSqrtPriceFromAmountInBRoundingDown(sqrtPrice, liquidity, amount) {
|
|
8899
|
+
const quotient = amount.shln(SCALE_OFFSET * 2).div(liquidity);
|
|
8900
|
+
const result = sqrtPrice.add(quotient);
|
|
8901
|
+
return result;
|
|
8902
|
+
}
|
|
8903
|
+
function getNextSqrtPriceFromAmountOutBRoundingDown(sqrtPrice, liquidity, amount) {
|
|
8904
|
+
const numerator = amount.shln(SCALE_OFFSET * 2);
|
|
8905
|
+
const quotient = numerator.add(liquidity).subn(1).div(liquidity);
|
|
8906
|
+
const result = sqrtPrice.sub(quotient);
|
|
8907
|
+
if (result.isNeg()) {
|
|
8908
|
+
throw new Error("sqrt price cannot be negative");
|
|
7994
8909
|
}
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
|
|
8910
|
+
return result;
|
|
8911
|
+
}
|
|
8912
|
+
function getNextSqrtPriceFromAmountInARoundingUp(sqrtPrice, liquidity, amount) {
|
|
8913
|
+
if (amount.isZero()) {
|
|
8914
|
+
return sqrtPrice;
|
|
8915
|
+
}
|
|
8916
|
+
const product = amount.mul(sqrtPrice);
|
|
8917
|
+
const denominator = liquidity.add(product);
|
|
8918
|
+
const result = mulDiv(liquidity, sqrtPrice, denominator, 0 /* Up */);
|
|
8919
|
+
return result;
|
|
8920
|
+
}
|
|
8921
|
+
function getNextSqrtPriceFromAmountOutARoundingUp(sqrtPrice, liquidity, amount) {
|
|
8922
|
+
if (amount.isZero()) {
|
|
8923
|
+
return sqrtPrice;
|
|
8924
|
+
}
|
|
8925
|
+
const product = amount.mul(sqrtPrice);
|
|
8926
|
+
const denominator = liquidity.sub(product);
|
|
8927
|
+
if (denominator.lte(new BN11(0))) {
|
|
8928
|
+
throw new Error("MathOverflow: denominator is zero or negative");
|
|
8929
|
+
}
|
|
8930
|
+
return mulDiv(liquidity, sqrtPrice, denominator, 0 /* Up */);
|
|
8931
|
+
}
|
|
8932
|
+
function getNextSqrtPriceFromOutput(sqrtPrice, liquidity, amountOut, aForB) {
|
|
8933
|
+
if (sqrtPrice.lte(new BN11(0))) {
|
|
8934
|
+
throw new Error("sqrtPrice must be greater than 0");
|
|
8935
|
+
}
|
|
8936
|
+
if (liquidity.lte(new BN11(0))) {
|
|
8937
|
+
throw new Error("liquidity must be greater than 0");
|
|
8938
|
+
}
|
|
8939
|
+
if (aForB) {
|
|
8940
|
+
return getNextSqrtPriceFromAmountOutBRoundingDown(
|
|
8941
|
+
sqrtPrice,
|
|
8942
|
+
liquidity,
|
|
8943
|
+
amountOut
|
|
8944
|
+
);
|
|
8945
|
+
} else {
|
|
8946
|
+
return getNextSqrtPriceFromAmountOutARoundingUp(
|
|
8947
|
+
sqrtPrice,
|
|
8948
|
+
liquidity,
|
|
8949
|
+
amountOut
|
|
8950
|
+
);
|
|
8951
|
+
}
|
|
8952
|
+
}
|
|
8953
|
+
function getNextSqrtPriceFromInput(sqrtPrice, liquidity, amountIn, aForB) {
|
|
8954
|
+
if (sqrtPrice.lte(new BN11(0))) {
|
|
8955
|
+
throw new Error("sqrtPrice must be greater than 0");
|
|
8956
|
+
}
|
|
8957
|
+
if (liquidity.lte(new BN11(0))) {
|
|
8958
|
+
throw new Error("liquidity must be greater than 0");
|
|
8959
|
+
}
|
|
8960
|
+
if (aForB) {
|
|
8961
|
+
return getNextSqrtPriceFromAmountInARoundingUp(
|
|
8962
|
+
sqrtPrice,
|
|
8963
|
+
liquidity,
|
|
8964
|
+
amountIn
|
|
8965
|
+
);
|
|
8966
|
+
} else {
|
|
8967
|
+
return getNextSqrtPriceFromAmountInBRoundingDown(
|
|
8968
|
+
sqrtPrice,
|
|
8969
|
+
liquidity,
|
|
8970
|
+
amountIn
|
|
8971
|
+
);
|
|
8972
|
+
}
|
|
8973
|
+
}
|
|
8974
|
+
function getAmountBFromLiquidityDelta(lowerSqrtPrice, upperSqrtPrice, liquidity, rounding) {
|
|
8975
|
+
const result = getDeltaAmountBUnsignedUnchecked(
|
|
8976
|
+
lowerSqrtPrice,
|
|
8977
|
+
upperSqrtPrice,
|
|
8978
|
+
liquidity,
|
|
8979
|
+
rounding
|
|
7999
8980
|
);
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8981
|
+
return result;
|
|
8982
|
+
}
|
|
8983
|
+
function getDeltaAmountBUnsignedUnchecked(lowerSqrtPrice, upperSqrtPrice, liquidity, rounding) {
|
|
8984
|
+
const deltaSqrtPrice = upperSqrtPrice.sub(lowerSqrtPrice);
|
|
8985
|
+
const prod = liquidity.mul(deltaSqrtPrice);
|
|
8986
|
+
const shift = SCALE_OFFSET * 2;
|
|
8987
|
+
if (rounding === 0 /* Up */) {
|
|
8988
|
+
const denominator = new BN11(1).ushln(shift);
|
|
8989
|
+
const result = prod.add(denominator.subn(1)).div(denominator);
|
|
8990
|
+
return result;
|
|
8991
|
+
} else {
|
|
8992
|
+
const result = prod.ushrn(shift);
|
|
8993
|
+
return result;
|
|
8994
|
+
}
|
|
8995
|
+
}
|
|
8996
|
+
function getAmountAFromLiquidityDelta(lowerSqrtPrice, upperSqrtPrice, liquidity, rounding) {
|
|
8997
|
+
const result = getDeltaAmountAUnsignedUnchecked(
|
|
8998
|
+
lowerSqrtPrice,
|
|
8999
|
+
upperSqrtPrice,
|
|
9000
|
+
liquidity,
|
|
9001
|
+
rounding
|
|
8005
9002
|
);
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
|
|
8009
|
-
|
|
9003
|
+
return result;
|
|
9004
|
+
}
|
|
9005
|
+
function getDeltaAmountAUnsignedUnchecked(lowerSqrtPrice, upperSqrtPrice, liquidity, rounding) {
|
|
9006
|
+
const numerator1 = liquidity;
|
|
9007
|
+
const numerator2 = upperSqrtPrice.sub(lowerSqrtPrice);
|
|
9008
|
+
const denominator = lowerSqrtPrice.mul(upperSqrtPrice);
|
|
9009
|
+
if (denominator.lte(new BN11(0))) {
|
|
9010
|
+
throw new Error("Denominator must be greater than zero");
|
|
9011
|
+
}
|
|
9012
|
+
const result = mulDiv(numerator1, numerator2, denominator, rounding);
|
|
9013
|
+
return result;
|
|
9014
|
+
}
|
|
9015
|
+
function getLiquidityDeltaFromAmountA(amountA, lowerSqrtPrice, upperSqrtPrice) {
|
|
9016
|
+
const product = amountA.mul(lowerSqrtPrice).mul(upperSqrtPrice);
|
|
9017
|
+
const denominator = upperSqrtPrice.sub(lowerSqrtPrice);
|
|
9018
|
+
return product.div(denominator);
|
|
9019
|
+
}
|
|
9020
|
+
function getLiquidityDeltaFromAmountB(amountB, lowerSqrtPrice, upperSqrtPrice) {
|
|
9021
|
+
const denominator = upperSqrtPrice.sub(lowerSqrtPrice);
|
|
9022
|
+
const product = amountB.shln(128);
|
|
9023
|
+
return product.div(denominator);
|
|
9024
|
+
}
|
|
9025
|
+
|
|
9026
|
+
// src/math/quote.ts
|
|
9027
|
+
function getSwapResultFromExactInput(poolState, amountIn, feeMode, tradeDirection, currentPoint) {
|
|
9028
|
+
let actualProtocolFee = new BN12(0);
|
|
9029
|
+
let actualTradingFee = new BN12(0);
|
|
9030
|
+
let actualReferralFee = new BN12(0);
|
|
9031
|
+
let actualPartnerFee = new BN12(0);
|
|
9032
|
+
const maxFeeNumerator = getMaxFeeNumerator(poolState.version);
|
|
9033
|
+
const tradeFeeNumerator = getTotalTradingFeeFromIncludedFeeAmount(
|
|
9034
|
+
poolState.poolFees,
|
|
9035
|
+
currentPoint,
|
|
9036
|
+
poolState.activationPoint,
|
|
9037
|
+
amountIn,
|
|
9038
|
+
tradeDirection,
|
|
9039
|
+
maxFeeNumerator
|
|
9040
|
+
);
|
|
9041
|
+
let actualAmountIn;
|
|
9042
|
+
if (feeMode.feesOnInput) {
|
|
9043
|
+
const { amount, tradingFee, protocolFee, partnerFee, referralFee } = getFeeOnAmount(
|
|
9044
|
+
poolState.poolFees,
|
|
9045
|
+
amountIn,
|
|
9046
|
+
tradeFeeNumerator,
|
|
9047
|
+
feeMode.hasReferral,
|
|
9048
|
+
hasPartner(poolState)
|
|
9049
|
+
);
|
|
9050
|
+
actualProtocolFee = protocolFee;
|
|
9051
|
+
actualTradingFee = tradingFee;
|
|
9052
|
+
actualReferralFee = referralFee;
|
|
9053
|
+
actualPartnerFee = partnerFee;
|
|
9054
|
+
actualAmountIn = amount;
|
|
8010
9055
|
} else {
|
|
8011
|
-
|
|
9056
|
+
actualAmountIn = amountIn;
|
|
8012
9057
|
}
|
|
8013
|
-
|
|
8014
|
-
|
|
8015
|
-
|
|
8016
|
-
|
|
8017
|
-
|
|
8018
|
-
|
|
8019
|
-
};
|
|
8020
|
-
|
|
8021
|
-
|
|
8022
|
-
|
|
8023
|
-
|
|
8024
|
-
}
|
|
8025
|
-
|
|
8026
|
-
|
|
8027
|
-
|
|
8028
|
-
|
|
9058
|
+
let swapAmountFromInput;
|
|
9059
|
+
if (tradeDirection === 0 /* AtoB */) {
|
|
9060
|
+
swapAmountFromInput = calculateAtoBFromAmountIn(poolState, actualAmountIn);
|
|
9061
|
+
} else {
|
|
9062
|
+
swapAmountFromInput = calculateBtoAFromAmountIn(poolState, actualAmountIn);
|
|
9063
|
+
}
|
|
9064
|
+
const { outputAmount, nextSqrtPrice, amountLeft } = swapAmountFromInput;
|
|
9065
|
+
let actualAmountOut;
|
|
9066
|
+
if (feeMode.feesOnInput) {
|
|
9067
|
+
actualAmountOut = outputAmount;
|
|
9068
|
+
} else {
|
|
9069
|
+
const { amount, tradingFee, protocolFee, partnerFee, referralFee } = getFeeOnAmount(
|
|
9070
|
+
poolState.poolFees,
|
|
9071
|
+
outputAmount,
|
|
9072
|
+
tradeFeeNumerator,
|
|
9073
|
+
feeMode.hasReferral,
|
|
9074
|
+
hasPartner(poolState)
|
|
9075
|
+
);
|
|
9076
|
+
actualProtocolFee = protocolFee;
|
|
9077
|
+
actualTradingFee = tradingFee;
|
|
9078
|
+
actualReferralFee = referralFee;
|
|
9079
|
+
actualPartnerFee = partnerFee;
|
|
9080
|
+
actualAmountOut = amount;
|
|
9081
|
+
}
|
|
9082
|
+
return {
|
|
9083
|
+
amountLeft,
|
|
9084
|
+
includedFeeInputAmount: amountIn,
|
|
9085
|
+
excludedFeeInputAmount: actualAmountIn,
|
|
9086
|
+
outputAmount: actualAmountOut,
|
|
9087
|
+
nextSqrtPrice,
|
|
9088
|
+
tradingFee: actualTradingFee,
|
|
9089
|
+
protocolFee: actualProtocolFee,
|
|
9090
|
+
partnerFee: actualPartnerFee,
|
|
9091
|
+
referralFee: actualReferralFee
|
|
9092
|
+
};
|
|
9093
|
+
}
|
|
9094
|
+
function calculateAtoBFromAmountIn(poolState, amountIn) {
|
|
9095
|
+
const nextSqrtPrice = getNextSqrtPriceFromInput(
|
|
9096
|
+
poolState.sqrtPrice,
|
|
9097
|
+
poolState.liquidity,
|
|
9098
|
+
amountIn,
|
|
9099
|
+
true
|
|
9100
|
+
);
|
|
9101
|
+
if (nextSqrtPrice.lt(poolState.sqrtMinPrice)) {
|
|
9102
|
+
throw new Error("Price range is violated");
|
|
9103
|
+
}
|
|
9104
|
+
const outputAmount = getAmountBFromLiquidityDelta(
|
|
9105
|
+
nextSqrtPrice,
|
|
9106
|
+
poolState.sqrtPrice,
|
|
9107
|
+
poolState.liquidity,
|
|
9108
|
+
1 /* Down */
|
|
8029
9109
|
);
|
|
8030
|
-
const sqrtValue = Decimal3.sqrt(adjustedByDecimals);
|
|
8031
|
-
const sqrtValueQ64 = sqrtValue.mul(Decimal3.pow(2, 64));
|
|
8032
|
-
return new BN6(sqrtValueQ64.floor().toFixed());
|
|
8033
|
-
};
|
|
8034
|
-
var getUnClaimReward = (poolState, positionState) => {
|
|
8035
|
-
const totalPositionLiquidity = positionState.unlockedLiquidity.add(positionState.vestedLiquidity).add(positionState.permanentLockedLiquidity);
|
|
8036
|
-
const feeAPerTokenStored = new BN6(
|
|
8037
|
-
Buffer.from(poolState.feeAPerLiquidity).reverse()
|
|
8038
|
-
).sub(new BN6(Buffer.from(positionState.feeAPerTokenCheckpoint).reverse()));
|
|
8039
|
-
const feeBPerTokenStored = new BN6(
|
|
8040
|
-
Buffer.from(poolState.feeBPerLiquidity).reverse()
|
|
8041
|
-
).sub(new BN6(Buffer.from(positionState.feeBPerTokenCheckpoint).reverse()));
|
|
8042
|
-
const feeA = totalPositionLiquidity.mul(feeAPerTokenStored).shrn(LIQUIDITY_SCALE);
|
|
8043
|
-
const feeB = totalPositionLiquidity.mul(feeBPerTokenStored).shrn(LIQUIDITY_SCALE);
|
|
8044
9110
|
return {
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
9111
|
+
outputAmount,
|
|
9112
|
+
nextSqrtPrice,
|
|
9113
|
+
amountLeft: new BN12(0)
|
|
8048
9114
|
};
|
|
8049
|
-
}
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
9115
|
+
}
|
|
9116
|
+
function calculateBtoAFromAmountIn(poolState, amountIn) {
|
|
9117
|
+
const nextSqrtPrice = getNextSqrtPriceFromInput(
|
|
9118
|
+
poolState.sqrtPrice,
|
|
9119
|
+
poolState.liquidity,
|
|
9120
|
+
amountIn,
|
|
9121
|
+
false
|
|
9122
|
+
);
|
|
9123
|
+
if (nextSqrtPrice.gt(poolState.sqrtMaxPrice)) {
|
|
9124
|
+
throw new Error("Price range is violated");
|
|
9125
|
+
}
|
|
9126
|
+
const outputAmount = getAmountAFromLiquidityDelta(
|
|
9127
|
+
poolState.sqrtPrice,
|
|
9128
|
+
nextSqrtPrice,
|
|
9129
|
+
poolState.liquidity,
|
|
9130
|
+
1 /* Down */
|
|
9131
|
+
);
|
|
8053
9132
|
return {
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
9133
|
+
outputAmount,
|
|
9134
|
+
nextSqrtPrice,
|
|
9135
|
+
amountLeft: new BN12(0)
|
|
9136
|
+
};
|
|
9137
|
+
}
|
|
9138
|
+
function getSwapResultFromPartialInput(poolState, amountIn, feeMode, tradeDirection, currentPoint) {
|
|
9139
|
+
let actualProtocolFee = new BN12(0);
|
|
9140
|
+
let actualTradingFee = new BN12(0);
|
|
9141
|
+
let actualReferralFee = new BN12(0);
|
|
9142
|
+
let actualPartnerFee = new BN12(0);
|
|
9143
|
+
const maxFeeNumerator = getMaxFeeNumerator(poolState.version);
|
|
9144
|
+
const tradeFeeNumerator = getTotalTradingFeeFromIncludedFeeAmount(
|
|
9145
|
+
poolState.poolFees,
|
|
9146
|
+
currentPoint,
|
|
9147
|
+
poolState.activationPoint,
|
|
9148
|
+
amountIn,
|
|
9149
|
+
tradeDirection,
|
|
9150
|
+
maxFeeNumerator
|
|
9151
|
+
);
|
|
9152
|
+
let actualAmountIn;
|
|
9153
|
+
if (feeMode.feesOnInput) {
|
|
9154
|
+
const { amount, tradingFee, protocolFee, partnerFee, referralFee } = getFeeOnAmount(
|
|
9155
|
+
poolState.poolFees,
|
|
9156
|
+
amountIn,
|
|
9157
|
+
tradeFeeNumerator,
|
|
9158
|
+
feeMode.hasReferral,
|
|
9159
|
+
hasPartner(poolState)
|
|
9160
|
+
);
|
|
9161
|
+
actualProtocolFee = protocolFee;
|
|
9162
|
+
actualTradingFee = tradingFee;
|
|
9163
|
+
actualReferralFee = referralFee;
|
|
9164
|
+
actualPartnerFee = partnerFee;
|
|
9165
|
+
actualAmountIn = amount;
|
|
9166
|
+
} else {
|
|
9167
|
+
actualAmountIn = amountIn;
|
|
9168
|
+
}
|
|
9169
|
+
let swapAmountFromInput;
|
|
9170
|
+
if (tradeDirection === 0 /* AtoB */) {
|
|
9171
|
+
swapAmountFromInput = calculateAtoBFromPartialAmountIn(
|
|
9172
|
+
poolState,
|
|
9173
|
+
actualAmountIn
|
|
9174
|
+
);
|
|
9175
|
+
} else {
|
|
9176
|
+
swapAmountFromInput = calculateBtoAFromPartialAmountIn(
|
|
9177
|
+
poolState,
|
|
9178
|
+
actualAmountIn
|
|
9179
|
+
);
|
|
9180
|
+
}
|
|
9181
|
+
let { amountLeft, outputAmount, nextSqrtPrice } = swapAmountFromInput;
|
|
9182
|
+
let includedFeeInputAmount;
|
|
9183
|
+
if (amountLeft.gt(new BN12(0))) {
|
|
9184
|
+
actualAmountIn = actualAmountIn.sub(amountLeft);
|
|
9185
|
+
if (feeMode.feesOnInput) {
|
|
9186
|
+
const tradeFeeNumerator2 = getTotalTradingFeeFromExcludedFeeAmount(
|
|
9187
|
+
poolState.poolFees,
|
|
9188
|
+
currentPoint,
|
|
9189
|
+
poolState.activationPoint,
|
|
9190
|
+
actualAmountIn,
|
|
9191
|
+
tradeDirection,
|
|
9192
|
+
maxFeeNumerator
|
|
9193
|
+
);
|
|
9194
|
+
const { includedFeeAmount, feeAmount } = getIncludedFeeAmount(
|
|
9195
|
+
tradeFeeNumerator2,
|
|
9196
|
+
actualAmountIn
|
|
9197
|
+
);
|
|
9198
|
+
const { tradingFee, protocolFee, referralFee, partnerFee } = splitFees(
|
|
9199
|
+
poolState.poolFees,
|
|
9200
|
+
feeAmount,
|
|
9201
|
+
feeMode.hasReferral,
|
|
9202
|
+
hasPartner(poolState)
|
|
9203
|
+
);
|
|
9204
|
+
actualProtocolFee = protocolFee;
|
|
9205
|
+
actualTradingFee = tradingFee;
|
|
9206
|
+
actualReferralFee = referralFee;
|
|
9207
|
+
actualPartnerFee = partnerFee;
|
|
9208
|
+
includedFeeInputAmount = includedFeeAmount;
|
|
9209
|
+
} else {
|
|
9210
|
+
includedFeeInputAmount = actualAmountIn;
|
|
8057
9211
|
}
|
|
9212
|
+
} else {
|
|
9213
|
+
includedFeeInputAmount = amountIn;
|
|
9214
|
+
}
|
|
9215
|
+
let actualAmountOut;
|
|
9216
|
+
if (feeMode.feesOnInput) {
|
|
9217
|
+
actualAmountOut = outputAmount;
|
|
9218
|
+
} else {
|
|
9219
|
+
const { amount, tradingFee, protocolFee, partnerFee, referralFee } = getFeeOnAmount(
|
|
9220
|
+
poolState.poolFees,
|
|
9221
|
+
outputAmount,
|
|
9222
|
+
tradeFeeNumerator,
|
|
9223
|
+
feeMode.hasReferral,
|
|
9224
|
+
hasPartner(poolState)
|
|
9225
|
+
);
|
|
9226
|
+
actualProtocolFee = protocolFee;
|
|
9227
|
+
actualTradingFee = tradingFee;
|
|
9228
|
+
actualReferralFee = referralFee;
|
|
9229
|
+
actualPartnerFee = partnerFee;
|
|
9230
|
+
actualAmountOut = amount;
|
|
9231
|
+
}
|
|
9232
|
+
return {
|
|
9233
|
+
includedFeeInputAmount,
|
|
9234
|
+
excludedFeeInputAmount: actualAmountIn,
|
|
9235
|
+
amountLeft,
|
|
9236
|
+
outputAmount: actualAmountOut,
|
|
9237
|
+
nextSqrtPrice,
|
|
9238
|
+
tradingFee: actualTradingFee,
|
|
9239
|
+
protocolFee: actualProtocolFee,
|
|
9240
|
+
partnerFee: actualPartnerFee,
|
|
9241
|
+
referralFee: actualReferralFee
|
|
8058
9242
|
};
|
|
8059
|
-
}
|
|
8060
|
-
|
|
9243
|
+
}
|
|
9244
|
+
function calculateAtoBFromPartialAmountIn(poolState, amountIn) {
|
|
9245
|
+
const maxAmountIn = getAmountAFromLiquidityDelta(
|
|
9246
|
+
poolState.sqrtMinPrice,
|
|
9247
|
+
poolState.sqrtPrice,
|
|
9248
|
+
poolState.liquidity,
|
|
9249
|
+
0 /* Up */
|
|
9250
|
+
);
|
|
9251
|
+
let consumedInAmount;
|
|
9252
|
+
let nextSqrtPrice;
|
|
9253
|
+
if (amountIn.gte(maxAmountIn)) {
|
|
9254
|
+
consumedInAmount = maxAmountIn;
|
|
9255
|
+
nextSqrtPrice = poolState.sqrtMinPrice;
|
|
9256
|
+
} else {
|
|
9257
|
+
nextSqrtPrice = getNextSqrtPriceFromInput(
|
|
9258
|
+
poolState.sqrtPrice,
|
|
9259
|
+
poolState.liquidity,
|
|
9260
|
+
amountIn,
|
|
9261
|
+
true
|
|
9262
|
+
);
|
|
9263
|
+
consumedInAmount = amountIn;
|
|
9264
|
+
}
|
|
9265
|
+
const outputAmount = getAmountBFromLiquidityDelta(
|
|
9266
|
+
nextSqrtPrice,
|
|
9267
|
+
poolState.sqrtPrice,
|
|
9268
|
+
poolState.liquidity,
|
|
9269
|
+
1 /* Down */
|
|
9270
|
+
);
|
|
9271
|
+
const amountLeft = amountIn.sub(consumedInAmount);
|
|
8061
9272
|
return {
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
}
|
|
9273
|
+
outputAmount,
|
|
9274
|
+
nextSqrtPrice,
|
|
9275
|
+
amountLeft
|
|
8066
9276
|
};
|
|
8067
|
-
}
|
|
9277
|
+
}
|
|
9278
|
+
function calculateBtoAFromPartialAmountIn(poolState, amountIn) {
|
|
9279
|
+
const maxAmountIn = getAmountBFromLiquidityDelta(
|
|
9280
|
+
poolState.sqrtPrice,
|
|
9281
|
+
poolState.sqrtMaxPrice,
|
|
9282
|
+
poolState.liquidity,
|
|
9283
|
+
0 /* Up */
|
|
9284
|
+
);
|
|
9285
|
+
let consumedInAmount;
|
|
9286
|
+
let nextSqrtPrice;
|
|
9287
|
+
if (amountIn.gte(maxAmountIn)) {
|
|
9288
|
+
consumedInAmount = maxAmountIn;
|
|
9289
|
+
nextSqrtPrice = poolState.sqrtMaxPrice;
|
|
9290
|
+
} else {
|
|
9291
|
+
nextSqrtPrice = getNextSqrtPriceFromInput(
|
|
9292
|
+
poolState.sqrtPrice,
|
|
9293
|
+
poolState.liquidity,
|
|
9294
|
+
amountIn,
|
|
9295
|
+
false
|
|
9296
|
+
);
|
|
9297
|
+
consumedInAmount = amountIn;
|
|
9298
|
+
}
|
|
9299
|
+
const outputAmount = getAmountAFromLiquidityDelta(
|
|
9300
|
+
poolState.sqrtPrice,
|
|
9301
|
+
nextSqrtPrice,
|
|
9302
|
+
poolState.liquidity,
|
|
9303
|
+
1 /* Down */
|
|
9304
|
+
);
|
|
9305
|
+
const amountLeft = amountIn.sub(consumedInAmount);
|
|
9306
|
+
return {
|
|
9307
|
+
outputAmount,
|
|
9308
|
+
nextSqrtPrice,
|
|
9309
|
+
amountLeft
|
|
9310
|
+
};
|
|
9311
|
+
}
|
|
9312
|
+
function getSwapResultFromExactOutput(poolState, amountOut, feeMode, tradeDirection, currentPoint) {
|
|
9313
|
+
let actualProtocolFee = new BN12(0);
|
|
9314
|
+
let actualTradingFee = new BN12(0);
|
|
9315
|
+
let actualReferralFee = new BN12(0);
|
|
9316
|
+
let actualPartnerFee = new BN12(0);
|
|
9317
|
+
const maxFeeNumerator = getMaxFeeNumerator(poolState.version);
|
|
9318
|
+
let includedFeeAmountOut;
|
|
9319
|
+
if (feeMode.feesOnInput) {
|
|
9320
|
+
includedFeeAmountOut = amountOut;
|
|
9321
|
+
} else {
|
|
9322
|
+
const tradeFeeNumerator = getTotalTradingFeeFromExcludedFeeAmount(
|
|
9323
|
+
poolState.poolFees,
|
|
9324
|
+
currentPoint,
|
|
9325
|
+
poolState.activationPoint,
|
|
9326
|
+
amountOut,
|
|
9327
|
+
tradeDirection,
|
|
9328
|
+
maxFeeNumerator
|
|
9329
|
+
);
|
|
9330
|
+
const { includedFeeAmount, feeAmount } = getIncludedFeeAmount(
|
|
9331
|
+
tradeFeeNumerator,
|
|
9332
|
+
amountOut
|
|
9333
|
+
);
|
|
9334
|
+
const split = splitFees(
|
|
9335
|
+
poolState.poolFees,
|
|
9336
|
+
feeAmount,
|
|
9337
|
+
feeMode.hasReferral,
|
|
9338
|
+
hasPartner(poolState)
|
|
9339
|
+
);
|
|
9340
|
+
actualTradingFee = split.tradingFee;
|
|
9341
|
+
actualProtocolFee = split.protocolFee;
|
|
9342
|
+
actualReferralFee = split.referralFee;
|
|
9343
|
+
actualPartnerFee = split.partnerFee;
|
|
9344
|
+
includedFeeAmountOut = includedFeeAmount;
|
|
9345
|
+
}
|
|
9346
|
+
let swapAmountFromOutput;
|
|
9347
|
+
if (tradeDirection === 0 /* AtoB */) {
|
|
9348
|
+
swapAmountFromOutput = calculateAtoBFromAmountOut(
|
|
9349
|
+
poolState,
|
|
9350
|
+
includedFeeAmountOut
|
|
9351
|
+
);
|
|
9352
|
+
} else {
|
|
9353
|
+
swapAmountFromOutput = calculateBtoAFromAmountOut(
|
|
9354
|
+
poolState,
|
|
9355
|
+
includedFeeAmountOut
|
|
9356
|
+
);
|
|
9357
|
+
}
|
|
9358
|
+
const { inputAmount, nextSqrtPrice } = swapAmountFromOutput;
|
|
9359
|
+
let includedFeeInputAmount;
|
|
9360
|
+
if (feeMode.feesOnInput) {
|
|
9361
|
+
const tradeFeeNumerator = getTotalTradingFeeFromExcludedFeeAmount(
|
|
9362
|
+
poolState.poolFees,
|
|
9363
|
+
currentPoint,
|
|
9364
|
+
poolState.activationPoint,
|
|
9365
|
+
inputAmount,
|
|
9366
|
+
tradeDirection,
|
|
9367
|
+
maxFeeNumerator
|
|
9368
|
+
);
|
|
9369
|
+
const { includedFeeAmount, feeAmount } = getIncludedFeeAmount(
|
|
9370
|
+
tradeFeeNumerator,
|
|
9371
|
+
inputAmount
|
|
9372
|
+
);
|
|
9373
|
+
const split = splitFees(
|
|
9374
|
+
poolState.poolFees,
|
|
9375
|
+
feeAmount,
|
|
9376
|
+
feeMode.hasReferral,
|
|
9377
|
+
hasPartner(poolState)
|
|
9378
|
+
);
|
|
9379
|
+
actualTradingFee = split.tradingFee;
|
|
9380
|
+
actualProtocolFee = split.protocolFee;
|
|
9381
|
+
actualReferralFee = split.referralFee;
|
|
9382
|
+
actualPartnerFee = split.partnerFee;
|
|
9383
|
+
includedFeeInputAmount = includedFeeAmount;
|
|
9384
|
+
} else {
|
|
9385
|
+
includedFeeInputAmount = inputAmount;
|
|
9386
|
+
}
|
|
9387
|
+
return {
|
|
9388
|
+
amountLeft: new BN12(0),
|
|
9389
|
+
includedFeeInputAmount,
|
|
9390
|
+
excludedFeeInputAmount: inputAmount,
|
|
9391
|
+
outputAmount: amountOut,
|
|
9392
|
+
nextSqrtPrice,
|
|
9393
|
+
tradingFee: actualTradingFee,
|
|
9394
|
+
protocolFee: actualProtocolFee,
|
|
9395
|
+
partnerFee: actualPartnerFee,
|
|
9396
|
+
referralFee: actualReferralFee
|
|
9397
|
+
};
|
|
9398
|
+
}
|
|
9399
|
+
function calculateAtoBFromAmountOut(poolState, amountOut) {
|
|
9400
|
+
const nextSqrtPrice = getNextSqrtPriceFromOutput(
|
|
9401
|
+
poolState.sqrtPrice,
|
|
9402
|
+
poolState.liquidity,
|
|
9403
|
+
amountOut,
|
|
9404
|
+
true
|
|
9405
|
+
);
|
|
9406
|
+
if (nextSqrtPrice.lt(poolState.sqrtMinPrice)) {
|
|
9407
|
+
throw new Error("Price Range Violation");
|
|
9408
|
+
}
|
|
9409
|
+
const inputAmount = getAmountAFromLiquidityDelta(
|
|
9410
|
+
nextSqrtPrice,
|
|
9411
|
+
poolState.sqrtPrice,
|
|
9412
|
+
poolState.liquidity,
|
|
9413
|
+
0 /* Up */
|
|
9414
|
+
);
|
|
9415
|
+
return {
|
|
9416
|
+
inputAmount,
|
|
9417
|
+
nextSqrtPrice
|
|
9418
|
+
};
|
|
9419
|
+
}
|
|
9420
|
+
function calculateBtoAFromAmountOut(poolState, amountOut) {
|
|
9421
|
+
const nextSqrtPrice = getNextSqrtPriceFromOutput(
|
|
9422
|
+
poolState.sqrtPrice,
|
|
9423
|
+
poolState.liquidity,
|
|
9424
|
+
amountOut,
|
|
9425
|
+
false
|
|
9426
|
+
);
|
|
9427
|
+
if (nextSqrtPrice.gt(poolState.sqrtMaxPrice)) {
|
|
9428
|
+
throw new Error("Price Range Violation");
|
|
9429
|
+
}
|
|
9430
|
+
const inputAmount = getAmountBFromLiquidityDelta(
|
|
9431
|
+
poolState.sqrtPrice,
|
|
9432
|
+
nextSqrtPrice,
|
|
9433
|
+
poolState.liquidity,
|
|
9434
|
+
0 /* Up */
|
|
9435
|
+
);
|
|
9436
|
+
return {
|
|
9437
|
+
inputAmount,
|
|
9438
|
+
nextSqrtPrice
|
|
9439
|
+
};
|
|
9440
|
+
}
|
|
9441
|
+
function swapQuoteExactInput(pool, currentPoint, amountIn, slippage, aToB, hasReferral, tokenADecimal, tokenBDecimal, inputTokenInfo, outputTokenInfo) {
|
|
9442
|
+
if (amountIn.lte(new BN12(0))) {
|
|
9443
|
+
throw new Error("Amount in must be greater than 0");
|
|
9444
|
+
}
|
|
9445
|
+
if (!isSwapEnabled(pool, currentPoint)) {
|
|
9446
|
+
throw new Error("Swap is disabled");
|
|
9447
|
+
}
|
|
9448
|
+
const tradeDirection = aToB ? 0 /* AtoB */ : 1 /* BtoA */;
|
|
9449
|
+
const feeMode = getFeeMode(pool.collectFeeMode, tradeDirection, hasReferral);
|
|
9450
|
+
let actualAmountIn = amountIn;
|
|
9451
|
+
if (inputTokenInfo) {
|
|
9452
|
+
actualAmountIn = calculateTransferFeeExcludedAmount(
|
|
9453
|
+
amountIn,
|
|
9454
|
+
inputTokenInfo.mint,
|
|
9455
|
+
inputTokenInfo.currentEpoch
|
|
9456
|
+
).amount;
|
|
9457
|
+
}
|
|
9458
|
+
const swapResult = getSwapResultFromExactInput(
|
|
9459
|
+
pool,
|
|
9460
|
+
actualAmountIn,
|
|
9461
|
+
feeMode,
|
|
9462
|
+
tradeDirection,
|
|
9463
|
+
currentPoint
|
|
9464
|
+
);
|
|
9465
|
+
let actualAmountOut = swapResult.outputAmount;
|
|
9466
|
+
if (outputTokenInfo) {
|
|
9467
|
+
actualAmountOut = calculateTransferFeeExcludedAmount(
|
|
9468
|
+
swapResult.outputAmount,
|
|
9469
|
+
outputTokenInfo.mint,
|
|
9470
|
+
outputTokenInfo.currentEpoch
|
|
9471
|
+
).amount;
|
|
9472
|
+
}
|
|
9473
|
+
const minimumAmountOut = getAmountWithSlippage(
|
|
9474
|
+
actualAmountOut,
|
|
9475
|
+
slippage,
|
|
9476
|
+
0 /* ExactIn */
|
|
9477
|
+
);
|
|
9478
|
+
const priceImpact = getPriceImpact(
|
|
9479
|
+
actualAmountIn,
|
|
9480
|
+
actualAmountOut,
|
|
9481
|
+
pool.sqrtPrice,
|
|
9482
|
+
aToB,
|
|
9483
|
+
tokenADecimal,
|
|
9484
|
+
tokenBDecimal
|
|
9485
|
+
);
|
|
9486
|
+
return __spreadProps(__spreadValues({}, swapResult), {
|
|
9487
|
+
minimumAmountOut,
|
|
9488
|
+
priceImpact
|
|
9489
|
+
});
|
|
9490
|
+
}
|
|
9491
|
+
function swapQuoteExactOutput(pool, currentPoint, amountOut, slippage, aToB, hasReferral, tokenADecimal, tokenBDecimal, inputTokenInfo, outputTokenInfo) {
|
|
9492
|
+
if (amountOut.lte(new BN12(0))) {
|
|
9493
|
+
throw new Error("Amount out must be greater than 0");
|
|
9494
|
+
}
|
|
9495
|
+
if (!isSwapEnabled(pool, currentPoint)) {
|
|
9496
|
+
throw new Error("Swap is disabled");
|
|
9497
|
+
}
|
|
9498
|
+
const tradeDirection = aToB ? 0 /* AtoB */ : 1 /* BtoA */;
|
|
9499
|
+
const feeMode = getFeeMode(pool.collectFeeMode, tradeDirection, hasReferral);
|
|
9500
|
+
let actualAmountOut = amountOut;
|
|
9501
|
+
if (outputTokenInfo) {
|
|
9502
|
+
actualAmountOut = calculateTransferFeeIncludedAmount(
|
|
9503
|
+
amountOut,
|
|
9504
|
+
outputTokenInfo.mint,
|
|
9505
|
+
outputTokenInfo.currentEpoch
|
|
9506
|
+
).amount;
|
|
9507
|
+
}
|
|
9508
|
+
const swapResult = getSwapResultFromExactOutput(
|
|
9509
|
+
pool,
|
|
9510
|
+
actualAmountOut,
|
|
9511
|
+
feeMode,
|
|
9512
|
+
tradeDirection,
|
|
9513
|
+
currentPoint
|
|
9514
|
+
);
|
|
9515
|
+
let actualAmountIn = swapResult.includedFeeInputAmount;
|
|
9516
|
+
if (inputTokenInfo) {
|
|
9517
|
+
actualAmountIn = calculateTransferFeeIncludedAmount(
|
|
9518
|
+
swapResult.includedFeeInputAmount,
|
|
9519
|
+
inputTokenInfo.mint,
|
|
9520
|
+
inputTokenInfo.currentEpoch
|
|
9521
|
+
).amount;
|
|
9522
|
+
}
|
|
9523
|
+
const maximumAmountIn = getAmountWithSlippage(
|
|
9524
|
+
actualAmountIn,
|
|
9525
|
+
slippage,
|
|
9526
|
+
2 /* ExactOut */
|
|
9527
|
+
);
|
|
9528
|
+
const priceImpact = getPriceImpact(
|
|
9529
|
+
actualAmountIn,
|
|
9530
|
+
actualAmountOut,
|
|
9531
|
+
pool.sqrtPrice,
|
|
9532
|
+
aToB,
|
|
9533
|
+
tokenADecimal,
|
|
9534
|
+
tokenBDecimal
|
|
9535
|
+
);
|
|
9536
|
+
return __spreadProps(__spreadValues({}, swapResult), {
|
|
9537
|
+
maximumAmountIn,
|
|
9538
|
+
priceImpact
|
|
9539
|
+
});
|
|
9540
|
+
}
|
|
9541
|
+
function swapQuotePartialInput(pool, currentPoint, amountIn, slippage, aToB, hasReferral, tokenADecimal, tokenBDecimal, inputTokenInfo, outputTokenInfo) {
|
|
9542
|
+
if (amountIn.lte(new BN12(0))) {
|
|
9543
|
+
throw new Error("Amount in must be greater than 0");
|
|
9544
|
+
}
|
|
9545
|
+
if (!isSwapEnabled(pool, currentPoint)) {
|
|
9546
|
+
throw new Error("Swap is disabled");
|
|
9547
|
+
}
|
|
9548
|
+
const tradeDirection = aToB ? 0 /* AtoB */ : 1 /* BtoA */;
|
|
9549
|
+
const feeMode = getFeeMode(pool.collectFeeMode, tradeDirection, hasReferral);
|
|
9550
|
+
let actualAmountIn = amountIn;
|
|
9551
|
+
if (inputTokenInfo) {
|
|
9552
|
+
actualAmountIn = calculateTransferFeeExcludedAmount(
|
|
9553
|
+
amountIn,
|
|
9554
|
+
inputTokenInfo.mint,
|
|
9555
|
+
inputTokenInfo.currentEpoch
|
|
9556
|
+
).amount;
|
|
9557
|
+
}
|
|
9558
|
+
const swapResult = getSwapResultFromPartialInput(
|
|
9559
|
+
pool,
|
|
9560
|
+
actualAmountIn,
|
|
9561
|
+
feeMode,
|
|
9562
|
+
tradeDirection,
|
|
9563
|
+
currentPoint
|
|
9564
|
+
);
|
|
9565
|
+
let actualAmountOut = swapResult.outputAmount;
|
|
9566
|
+
if (outputTokenInfo) {
|
|
9567
|
+
actualAmountOut = calculateTransferFeeExcludedAmount(
|
|
9568
|
+
swapResult.outputAmount,
|
|
9569
|
+
outputTokenInfo.mint,
|
|
9570
|
+
outputTokenInfo.currentEpoch
|
|
9571
|
+
).amount;
|
|
9572
|
+
}
|
|
9573
|
+
const minimumAmountOut = getAmountWithSlippage(
|
|
9574
|
+
actualAmountOut,
|
|
9575
|
+
slippage,
|
|
9576
|
+
1 /* PartialFill */
|
|
9577
|
+
);
|
|
9578
|
+
const priceImpact = getPriceImpact(
|
|
9579
|
+
actualAmountIn,
|
|
9580
|
+
actualAmountOut,
|
|
9581
|
+
pool.sqrtPrice,
|
|
9582
|
+
aToB,
|
|
9583
|
+
tokenADecimal,
|
|
9584
|
+
tokenBDecimal
|
|
9585
|
+
);
|
|
9586
|
+
return __spreadProps(__spreadValues({}, swapResult), {
|
|
9587
|
+
minimumAmountOut,
|
|
9588
|
+
priceImpact
|
|
9589
|
+
});
|
|
9590
|
+
}
|
|
8068
9591
|
|
|
8069
|
-
// src/
|
|
8070
|
-
import { BN as
|
|
8071
|
-
import
|
|
9592
|
+
// src/math/priceMath.ts
|
|
9593
|
+
import { BN as BN13 } from "@coral-xyz/anchor";
|
|
9594
|
+
import Decimal3 from "decimal.js";
|
|
8072
9595
|
function calculateInitSqrtPrice(tokenAAmount, tokenBAmount, minSqrtPrice, maxSqrtPrice) {
|
|
8073
9596
|
if (tokenAAmount.isZero() || tokenBAmount.isZero()) {
|
|
8074
9597
|
throw new Error("Amount cannot be zero");
|
|
8075
9598
|
}
|
|
8076
|
-
const amountADecimal = new
|
|
8077
|
-
const amountBDecimal = new
|
|
8078
|
-
const minSqrtPriceDecimal = new
|
|
8079
|
-
|
|
9599
|
+
const amountADecimal = new Decimal3(tokenAAmount.toString());
|
|
9600
|
+
const amountBDecimal = new Decimal3(tokenBAmount.toString());
|
|
9601
|
+
const minSqrtPriceDecimal = new Decimal3(minSqrtPrice.toString()).div(
|
|
9602
|
+
Decimal3.pow(2, 64)
|
|
8080
9603
|
);
|
|
8081
|
-
const maxSqrtPriceDecimal = new
|
|
8082
|
-
|
|
9604
|
+
const maxSqrtPriceDecimal = new Decimal3(maxSqrtPrice.toString()).div(
|
|
9605
|
+
Decimal3.pow(2, 64)
|
|
8083
9606
|
);
|
|
8084
|
-
const x = new
|
|
9607
|
+
const x = new Decimal3(1).div(maxSqrtPriceDecimal);
|
|
8085
9608
|
const y = amountBDecimal.div(amountADecimal);
|
|
8086
9609
|
const xy = x.mul(y);
|
|
8087
9610
|
const paMinusXY = minSqrtPriceDecimal.sub(xy);
|
|
8088
9611
|
const xyMinusPa = xy.sub(minSqrtPriceDecimal);
|
|
8089
|
-
const fourY = new
|
|
9612
|
+
const fourY = new Decimal3(4).mul(y);
|
|
8090
9613
|
const discriminant = xyMinusPa.mul(xyMinusPa).add(fourY);
|
|
8091
9614
|
const sqrtDiscriminant = discriminant.sqrt();
|
|
8092
|
-
const result = paMinusXY.add(sqrtDiscriminant).div(new
|
|
8093
|
-
return new
|
|
9615
|
+
const result = paMinusXY.add(sqrtDiscriminant).div(new Decimal3(2)).mul(Decimal3.pow(2, 64));
|
|
9616
|
+
return new BN13(result.floor().toFixed());
|
|
8094
9617
|
}
|
|
8095
9618
|
|
|
8096
|
-
// src/helpers/
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
|
|
8101
|
-
|
|
8102
|
-
MAX_FEE_BASIS_POINTS
|
|
8103
|
-
} from "@solana/spl-token";
|
|
8104
|
-
function calculatePreFeeAmount(transferFee, postFeeAmount) {
|
|
8105
|
-
if (postFeeAmount.isZero()) {
|
|
8106
|
-
return new BN8(0);
|
|
9619
|
+
// src/helpers/validation.ts
|
|
9620
|
+
function validateFeeScheduler(numberOfPeriod, periodFrequency, reductionFactor, cliffFeeNumerator, baseFeeMode, poolVersion) {
|
|
9621
|
+
if (!periodFrequency.eq(new BN14(0)) || numberOfPeriod !== 0 || !reductionFactor.eq(new BN14(0))) {
|
|
9622
|
+
if (numberOfPeriod === 0 || periodFrequency.eq(new BN14(0)) || reductionFactor.eq(new BN14(0))) {
|
|
9623
|
+
return false;
|
|
9624
|
+
}
|
|
8107
9625
|
}
|
|
8108
|
-
|
|
8109
|
-
|
|
9626
|
+
const minFeeNumerator = getMinBaseFeeNumerator(
|
|
9627
|
+
cliffFeeNumerator,
|
|
9628
|
+
numberOfPeriod,
|
|
9629
|
+
periodFrequency,
|
|
9630
|
+
reductionFactor,
|
|
9631
|
+
baseFeeMode
|
|
9632
|
+
);
|
|
9633
|
+
const maxFeeNumerator = getMaxBaseFeeNumerator(cliffFeeNumerator);
|
|
9634
|
+
validateFeeFraction(minFeeNumerator, new BN14(FEE_DENOMINATOR));
|
|
9635
|
+
validateFeeFraction(maxFeeNumerator, new BN14(FEE_DENOMINATOR));
|
|
9636
|
+
if (minFeeNumerator.lt(new BN14(MIN_FEE_NUMERATOR)) || maxFeeNumerator.gt(getMaxFeeNumerator(poolVersion))) {
|
|
9637
|
+
throw new Error("PoolError::ExceedMaxFeeBps");
|
|
8110
9638
|
}
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
|
|
9639
|
+
return true;
|
|
9640
|
+
}
|
|
9641
|
+
function validateFeeRateLimiter(cliffFeeNumerator, feeIncrementBps, maxFeeBps, maxLimiterDuration, referenceAmount, collectFeeMode, activationType, poolVersion) {
|
|
9642
|
+
if (collectFeeMode !== 1 /* OnlyB */) {
|
|
9643
|
+
return false;
|
|
8114
9644
|
}
|
|
8115
|
-
const
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
new BN8(transferFee.transferFeeBasisPoints)
|
|
9645
|
+
const maxFeeNumeratorFromBps = toNumerator(
|
|
9646
|
+
new BN14(maxFeeBps),
|
|
9647
|
+
new BN14(FEE_DENOMINATOR)
|
|
8119
9648
|
);
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
9649
|
+
if (cliffFeeNumerator.lt(new BN14(MIN_FEE_NUMERATOR)) || cliffFeeNumerator.gt(maxFeeNumeratorFromBps)) {
|
|
9650
|
+
return false;
|
|
9651
|
+
}
|
|
9652
|
+
if (isZeroRateLimiter(
|
|
9653
|
+
referenceAmount,
|
|
9654
|
+
maxLimiterDuration,
|
|
9655
|
+
maxFeeBps,
|
|
9656
|
+
feeIncrementBps
|
|
9657
|
+
)) {
|
|
9658
|
+
return true;
|
|
9659
|
+
}
|
|
9660
|
+
if (isNonZeroRateLimiter(
|
|
9661
|
+
referenceAmount,
|
|
9662
|
+
maxLimiterDuration,
|
|
9663
|
+
maxFeeBps,
|
|
9664
|
+
feeIncrementBps
|
|
9665
|
+
)) {
|
|
9666
|
+
return false;
|
|
9667
|
+
}
|
|
9668
|
+
const maxLimiterDurationLimit = activationType === 0 /* Slot */ ? new BN14(MAX_RATE_LIMITER_DURATION_IN_SLOTS) : new BN14(MAX_RATE_LIMITER_DURATION_IN_SECONDS);
|
|
9669
|
+
if (new BN14(maxLimiterDuration).gt(maxLimiterDurationLimit)) {
|
|
9670
|
+
return false;
|
|
9671
|
+
}
|
|
9672
|
+
const feeIncrementNumerator = toNumerator(
|
|
9673
|
+
new BN14(feeIncrementBps),
|
|
9674
|
+
new BN14(FEE_DENOMINATOR)
|
|
9675
|
+
);
|
|
9676
|
+
if (feeIncrementNumerator.gte(new BN14(FEE_DENOMINATOR))) {
|
|
9677
|
+
return false;
|
|
9678
|
+
}
|
|
9679
|
+
if (maxFeeBps > getMaxFeeBps(poolVersion)) {
|
|
9680
|
+
return false;
|
|
9681
|
+
}
|
|
9682
|
+
const minFeeNumerator = getFeeNumeratorFromIncludedFeeAmount(
|
|
9683
|
+
new BN14(0),
|
|
9684
|
+
cliffFeeNumerator,
|
|
9685
|
+
referenceAmount,
|
|
9686
|
+
maxFeeBps,
|
|
9687
|
+
feeIncrementBps
|
|
9688
|
+
);
|
|
9689
|
+
const maxFeeNumeratorFromAmount = getFeeNumeratorFromIncludedFeeAmount(
|
|
9690
|
+
new BN14(Number.MAX_SAFE_INTEGER),
|
|
9691
|
+
cliffFeeNumerator,
|
|
9692
|
+
referenceAmount,
|
|
9693
|
+
maxFeeBps,
|
|
9694
|
+
feeIncrementBps
|
|
9695
|
+
);
|
|
9696
|
+
if (minFeeNumerator.lt(new BN14(MIN_FEE_NUMERATOR)) || maxFeeNumeratorFromAmount.gt(getMaxFeeNumerator(poolVersion))) {
|
|
9697
|
+
return false;
|
|
8123
9698
|
}
|
|
8124
|
-
return
|
|
9699
|
+
return true;
|
|
8125
9700
|
}
|
|
8126
|
-
function
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
|
|
9701
|
+
function validateFeeFraction(numerator, denominator) {
|
|
9702
|
+
if (denominator.isZero() || numerator.gte(denominator)) {
|
|
9703
|
+
throw new Error(
|
|
9704
|
+
"InvalidFee: Fee numerator must be less than denominator and denominator must be non-zero"
|
|
9705
|
+
);
|
|
9706
|
+
}
|
|
9707
|
+
}
|
|
9708
|
+
|
|
9709
|
+
// src/helpers/common.ts
|
|
9710
|
+
import { PublicKey as PublicKey5 } from "@solana/web3.js";
|
|
9711
|
+
import BN15 from "bn.js";
|
|
9712
|
+
import Decimal4 from "decimal.js";
|
|
9713
|
+
function hasPartner(poolState) {
|
|
9714
|
+
return !poolState.partner.equals(PublicKey5.default);
|
|
9715
|
+
}
|
|
9716
|
+
function getCurrentPoint(connection, activationType) {
|
|
9717
|
+
return __async(this, null, function* () {
|
|
9718
|
+
const currentSlot = yield connection.getSlot();
|
|
9719
|
+
if (activationType === 0 /* Slot */) {
|
|
9720
|
+
return new BN15(currentSlot);
|
|
9721
|
+
} else {
|
|
9722
|
+
const currentTime = yield connection.getBlockTime(currentSlot);
|
|
9723
|
+
return new BN15(currentTime);
|
|
9724
|
+
}
|
|
9725
|
+
});
|
|
9726
|
+
}
|
|
9727
|
+
function isSwapEnabled(pool, currentPoint) {
|
|
9728
|
+
return pool.poolStatus === 0 /* Enable */ && currentPoint.gte(pool.activationPoint);
|
|
9729
|
+
}
|
|
9730
|
+
function convertToFeeSchedulerSecondFactor(value) {
|
|
9731
|
+
return Array.from(value.toArrayLike(Buffer, "le", 8));
|
|
9732
|
+
}
|
|
9733
|
+
function parseFeeSchedulerSecondFactor(secondFactor) {
|
|
9734
|
+
return new BN15(Buffer.from(secondFactor), "le");
|
|
9735
|
+
}
|
|
9736
|
+
function convertToRateLimiterSecondFactor(maxLimiterDuration, maxFeeBps) {
|
|
9737
|
+
const buffer1 = maxLimiterDuration.toArrayLike(Buffer, "le", 4);
|
|
9738
|
+
const buffer2 = maxFeeBps.toArrayLike(Buffer, "le", 4);
|
|
9739
|
+
const buffer = Buffer.concat([buffer1, buffer2]);
|
|
9740
|
+
return Array.from(buffer);
|
|
9741
|
+
}
|
|
9742
|
+
function parseRateLimiterSecondFactor(secondFactor) {
|
|
9743
|
+
const buffer = Buffer.from(secondFactor);
|
|
9744
|
+
return {
|
|
9745
|
+
maxLimiterDuration: buffer.readUInt32LE(0),
|
|
9746
|
+
maxFeeBps: buffer.readUInt32LE(4)
|
|
9747
|
+
};
|
|
9748
|
+
}
|
|
9749
|
+
function bpsToFeeNumerator(bps) {
|
|
9750
|
+
return new BN15(bps * FEE_DENOMINATOR).divn(BASIS_POINT_MAX);
|
|
9751
|
+
}
|
|
9752
|
+
function feeNumeratorToBps(feeNumerator) {
|
|
9753
|
+
return feeNumerator.muln(BASIS_POINT_MAX).div(new BN15(FEE_DENOMINATOR)).toNumber();
|
|
9754
|
+
}
|
|
9755
|
+
function convertToLamports(amount, tokenDecimal) {
|
|
9756
|
+
const valueInLamports = new Decimal4(amount).mul(
|
|
9757
|
+
Decimal4.pow(10, tokenDecimal)
|
|
8130
9758
|
);
|
|
9759
|
+
return fromDecimalToBN(valueInLamports);
|
|
8131
9760
|
}
|
|
8132
|
-
function
|
|
8133
|
-
|
|
9761
|
+
function fromDecimalToBN(value) {
|
|
9762
|
+
return new BN15(value.floor().toFixed());
|
|
9763
|
+
}
|
|
9764
|
+
function getFeeSchedulerParams(startingBaseFeeBps, endingBaseFeeBps, baseFeeMode, numberOfPeriod, totalDuration) {
|
|
9765
|
+
if (startingBaseFeeBps == endingBaseFeeBps) {
|
|
9766
|
+
if (numberOfPeriod != 0 || totalDuration != 0) {
|
|
9767
|
+
throw new Error("numberOfPeriod and totalDuration must both be zero");
|
|
9768
|
+
}
|
|
8134
9769
|
return {
|
|
8135
|
-
|
|
8136
|
-
|
|
9770
|
+
cliffFeeNumerator: bpsToFeeNumerator(startingBaseFeeBps),
|
|
9771
|
+
firstFactor: 0,
|
|
9772
|
+
secondFactor: Array.from(new BN15(0).toArrayLike(Buffer, "le", 8)),
|
|
9773
|
+
thirdFactor: new BN15(0),
|
|
9774
|
+
baseFeeMode: 0 /* FeeSchedulerLinear */
|
|
8137
9775
|
};
|
|
8138
9776
|
}
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
9777
|
+
if (numberOfPeriod <= 0) {
|
|
9778
|
+
throw new Error("Total periods must be greater than zero");
|
|
9779
|
+
}
|
|
9780
|
+
const poolMaxFeeBps = getMaxFeeBps(CURRENT_POOL_VERSION);
|
|
9781
|
+
if (startingBaseFeeBps > poolMaxFeeBps) {
|
|
9782
|
+
throw new Error(
|
|
9783
|
+
`startingBaseFeeBps (${startingBaseFeeBps} bps) exceeds maximum allowed value of ${poolMaxFeeBps} bps`
|
|
9784
|
+
);
|
|
9785
|
+
}
|
|
9786
|
+
if (endingBaseFeeBps > startingBaseFeeBps) {
|
|
9787
|
+
throw new Error(
|
|
9788
|
+
"endingBaseFeeBps bps must be less than or equal to startingBaseFeeBps bps"
|
|
9789
|
+
);
|
|
9790
|
+
}
|
|
9791
|
+
if (numberOfPeriod == 0 || totalDuration == 0) {
|
|
9792
|
+
throw new Error(
|
|
9793
|
+
"numberOfPeriod and totalDuration must both greater than zero"
|
|
9794
|
+
);
|
|
9795
|
+
}
|
|
9796
|
+
const maxBaseFeeNumerator = bpsToFeeNumerator(startingBaseFeeBps);
|
|
9797
|
+
const minBaseFeeNumerator = bpsToFeeNumerator(endingBaseFeeBps);
|
|
9798
|
+
const periodFrequency = new BN15(totalDuration / numberOfPeriod);
|
|
9799
|
+
const secondFactor = convertToFeeSchedulerSecondFactor(periodFrequency);
|
|
9800
|
+
let reductionFactor;
|
|
9801
|
+
if (baseFeeMode == 0 /* FeeSchedulerLinear */) {
|
|
9802
|
+
const totalReduction = maxBaseFeeNumerator.sub(minBaseFeeNumerator);
|
|
9803
|
+
reductionFactor = totalReduction.divn(numberOfPeriod);
|
|
9804
|
+
} else {
|
|
9805
|
+
const ratio = minBaseFeeNumerator.toNumber() / maxBaseFeeNumerator.toNumber();
|
|
9806
|
+
const decayBase = Math.pow(ratio, 1 / numberOfPeriod);
|
|
9807
|
+
reductionFactor = new BN15(BASIS_POINT_MAX * (1 - decayBase));
|
|
8145
9808
|
}
|
|
8146
|
-
const epochFee = getEpochFee(transferFeeConfig, BigInt(currentEpoch));
|
|
8147
|
-
const transferFee = epochFee.transferFeeBasisPoints == MAX_FEE_BASIS_POINTS ? new BN8(epochFee.maximumFee.toString()) : calculateInverseFee(epochFee, transferFeeExcludedAmount);
|
|
8148
|
-
const transferFeeIncludedAmount = transferFeeExcludedAmount.add(transferFee);
|
|
8149
9809
|
return {
|
|
8150
|
-
|
|
8151
|
-
|
|
9810
|
+
cliffFeeNumerator: maxBaseFeeNumerator,
|
|
9811
|
+
firstFactor: numberOfPeriod,
|
|
9812
|
+
secondFactor,
|
|
9813
|
+
thirdFactor: reductionFactor,
|
|
9814
|
+
baseFeeMode
|
|
8152
9815
|
};
|
|
8153
9816
|
}
|
|
8154
|
-
function
|
|
8155
|
-
const
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
|
|
8159
|
-
|
|
8160
|
-
|
|
9817
|
+
function getRateLimiterParams(baseFeeBps, feeIncrementBps, referenceAmount, maxLimiterDuration, maxFeeBps, tokenBDecimal, activationType) {
|
|
9818
|
+
const cliffFeeNumerator = bpsToFeeNumerator(baseFeeBps);
|
|
9819
|
+
const feeIncrementNumerator = bpsToFeeNumerator(feeIncrementBps);
|
|
9820
|
+
if (baseFeeBps <= 0 || feeIncrementBps <= 0 || referenceAmount <= 0 || maxLimiterDuration <= 0) {
|
|
9821
|
+
throw new Error("All rate limiter parameters must be greater than zero");
|
|
9822
|
+
}
|
|
9823
|
+
const poolMaxFeeBps = getMaxFeeBps(CURRENT_POOL_VERSION);
|
|
9824
|
+
const poolMaxFeeNumerator = getMaxFeeNumerator(CURRENT_POOL_VERSION);
|
|
9825
|
+
if (baseFeeBps > poolMaxFeeBps) {
|
|
9826
|
+
throw new Error(
|
|
9827
|
+
`Base fee (${baseFeeBps} bps) exceeds maximum allowed value of ${poolMaxFeeBps} bps`
|
|
9828
|
+
);
|
|
8161
9829
|
}
|
|
8162
|
-
|
|
8163
|
-
|
|
8164
|
-
|
|
8165
|
-
|
|
8166
|
-
|
|
8167
|
-
|
|
9830
|
+
if (feeIncrementBps > poolMaxFeeBps) {
|
|
9831
|
+
throw new Error(
|
|
9832
|
+
`Fee increment (${feeIncrementBps} bps) exceeds maximum allowed value of ${poolMaxFeeBps} bps`
|
|
9833
|
+
);
|
|
9834
|
+
}
|
|
9835
|
+
if (feeIncrementNumerator.gte(new BN15(FEE_DENOMINATOR))) {
|
|
9836
|
+
throw new Error(
|
|
9837
|
+
"Fee increment numerator must be less than FEE_DENOMINATOR"
|
|
9838
|
+
);
|
|
9839
|
+
}
|
|
9840
|
+
if (maxFeeBps > poolMaxFeeBps) {
|
|
9841
|
+
throw new Error(
|
|
9842
|
+
`Max fee (${maxFeeBps} bps) exceeds maximum allowed value of ${poolMaxFeeBps} bps for PoolVersion V${CURRENT_POOL_VERSION}`
|
|
9843
|
+
);
|
|
9844
|
+
}
|
|
9845
|
+
const deltaNumerator = new BN15(poolMaxFeeNumerator).sub(cliffFeeNumerator);
|
|
9846
|
+
const maxIndex = deltaNumerator.div(feeIncrementNumerator);
|
|
9847
|
+
if (maxIndex.lt(new BN15(1))) {
|
|
9848
|
+
throw new Error("Fee increment is too large for the given base fee");
|
|
9849
|
+
}
|
|
9850
|
+
if (cliffFeeNumerator.lt(new BN15(MIN_FEE_NUMERATOR)) || cliffFeeNumerator.gt(new BN15(poolMaxFeeNumerator))) {
|
|
9851
|
+
throw new Error("Base fee must be between 0.01% and 99%");
|
|
9852
|
+
}
|
|
9853
|
+
const maxDuration = activationType === 0 /* Slot */ ? MAX_RATE_LIMITER_DURATION_IN_SLOTS : MAX_RATE_LIMITER_DURATION_IN_SECONDS;
|
|
9854
|
+
if (maxLimiterDuration > maxDuration) {
|
|
9855
|
+
throw new Error(
|
|
9856
|
+
`Max duration exceeds maximum allowed value of ${maxDuration}`
|
|
9857
|
+
);
|
|
9858
|
+
}
|
|
9859
|
+
const referenceAmountInLamports = convertToLamports(
|
|
9860
|
+
referenceAmount,
|
|
9861
|
+
tokenBDecimal
|
|
8168
9862
|
);
|
|
8169
|
-
const
|
|
8170
|
-
|
|
9863
|
+
const secondFactor = convertToRateLimiterSecondFactor(
|
|
9864
|
+
new BN15(maxLimiterDuration),
|
|
9865
|
+
new BN15(maxFeeBps)
|
|
8171
9866
|
);
|
|
8172
9867
|
return {
|
|
8173
|
-
|
|
8174
|
-
|
|
9868
|
+
cliffFeeNumerator,
|
|
9869
|
+
firstFactor: feeIncrementBps,
|
|
9870
|
+
secondFactor,
|
|
9871
|
+
thirdFactor: new BN15(referenceAmountInLamports),
|
|
9872
|
+
baseFeeMode: 2 /* RateLimiter */
|
|
8175
9873
|
};
|
|
8176
9874
|
}
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
|
|
9875
|
+
function getBaseFeeParams(baseFeeParams, tokenBDecimal, activationType) {
|
|
9876
|
+
if (baseFeeParams.baseFeeMode === 2 /* RateLimiter */) {
|
|
9877
|
+
if (!baseFeeParams.rateLimiterParam) {
|
|
9878
|
+
throw new Error(
|
|
9879
|
+
"Rate limiter parameters are required for RateLimiter mode"
|
|
9880
|
+
);
|
|
9881
|
+
}
|
|
9882
|
+
const {
|
|
9883
|
+
baseFeeBps,
|
|
9884
|
+
feeIncrementBps,
|
|
9885
|
+
referenceAmount,
|
|
9886
|
+
maxLimiterDuration,
|
|
9887
|
+
maxFeeBps
|
|
9888
|
+
} = baseFeeParams.rateLimiterParam;
|
|
9889
|
+
return getRateLimiterParams(
|
|
9890
|
+
baseFeeBps,
|
|
9891
|
+
feeIncrementBps,
|
|
9892
|
+
referenceAmount,
|
|
9893
|
+
maxLimiterDuration,
|
|
9894
|
+
maxFeeBps,
|
|
9895
|
+
tokenBDecimal,
|
|
9896
|
+
activationType
|
|
9897
|
+
);
|
|
9898
|
+
} else {
|
|
9899
|
+
if (!baseFeeParams.feeSchedulerParam) {
|
|
9900
|
+
throw new Error(
|
|
9901
|
+
"Fee scheduler parameters are required for FeeScheduler mode"
|
|
9902
|
+
);
|
|
9903
|
+
}
|
|
9904
|
+
const { startingFeeBps, endingFeeBps, numberOfPeriod, totalDuration } = baseFeeParams.feeSchedulerParam;
|
|
9905
|
+
return getFeeSchedulerParams(
|
|
9906
|
+
startingFeeBps,
|
|
9907
|
+
endingFeeBps,
|
|
9908
|
+
baseFeeParams.baseFeeMode,
|
|
9909
|
+
numberOfPeriod,
|
|
9910
|
+
totalDuration
|
|
9911
|
+
);
|
|
8204
9912
|
}
|
|
8205
|
-
|
|
8206
|
-
|
|
9913
|
+
}
|
|
9914
|
+
function getDynamicFeeParams(baseFeeBps, maxPriceChangeBps = MAX_PRICE_CHANGE_BPS_DEFAULT) {
|
|
9915
|
+
if (maxPriceChangeBps > MAX_PRICE_CHANGE_BPS_DEFAULT) {
|
|
9916
|
+
throw new Error(
|
|
9917
|
+
`maxPriceChangeBps (${maxPriceChangeBps} bps) must be less than or equal to ${MAX_PRICE_CHANGE_BPS_DEFAULT}`
|
|
9918
|
+
);
|
|
8207
9919
|
}
|
|
8208
|
-
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
passedPeriod.mul(liquidityPerPeriod)
|
|
8212
|
-
);
|
|
8213
|
-
const availableReleasingLiquidity = unlockedLiquidity.sub(
|
|
8214
|
-
totalReleasedLiquidity
|
|
9920
|
+
const priceRatio = maxPriceChangeBps / BASIS_POINT_MAX + 1;
|
|
9921
|
+
const sqrtPriceRatioQ64 = new BN15(
|
|
9922
|
+
Decimal4.sqrt(priceRatio.toString()).mul(Decimal4.pow(2, 64)).floor().toFixed()
|
|
8215
9923
|
);
|
|
8216
|
-
|
|
9924
|
+
const deltaBinId = sqrtPriceRatioQ64.sub(ONE_Q64).div(BIN_STEP_BPS_U128_DEFAULT).muln(2);
|
|
9925
|
+
const maxVolatilityAccumulator = new BN15(deltaBinId.muln(BASIS_POINT_MAX));
|
|
9926
|
+
const squareVfaBin = maxVolatilityAccumulator.mul(new BN15(BIN_STEP_BPS_DEFAULT)).pow(new BN15(2));
|
|
9927
|
+
const baseFeeNumerator = new BN15(bpsToFeeNumerator(baseFeeBps));
|
|
9928
|
+
const maxDynamicFeeNumerator = baseFeeNumerator.muln(20).divn(100);
|
|
9929
|
+
const vFee = maxDynamicFeeNumerator.mul(new BN15(1e11)).sub(new BN15(99999999999));
|
|
9930
|
+
const variableFeeControl = vFee.div(squareVfaBin);
|
|
9931
|
+
return {
|
|
9932
|
+
binStep: BIN_STEP_BPS_DEFAULT,
|
|
9933
|
+
binStepU128: BIN_STEP_BPS_U128_DEFAULT,
|
|
9934
|
+
filterPeriod: DYNAMIC_FEE_FILTER_PERIOD_DEFAULT,
|
|
9935
|
+
decayPeriod: DYNAMIC_FEE_DECAY_PERIOD_DEFAULT,
|
|
9936
|
+
reductionFactor: DYNAMIC_FEE_REDUCTION_FACTOR_DEFAULT,
|
|
9937
|
+
maxVolatilityAccumulator: maxVolatilityAccumulator.toNumber(),
|
|
9938
|
+
variableFeeControl: variableFeeControl.toNumber()
|
|
9939
|
+
};
|
|
8217
9940
|
}
|
|
8218
9941
|
|
|
8219
9942
|
// src/CpAmm.ts
|
|
8220
|
-
import { min as min2, max } from "bn.js";
|
|
9943
|
+
import BN16, { min as min2, max } from "bn.js";
|
|
8221
9944
|
var CpAmm = class {
|
|
8222
9945
|
constructor(connection) {
|
|
8223
9946
|
this._program = new Program(cp_amm_default, {
|
|
@@ -8932,158 +10655,101 @@ var CpAmm = class {
|
|
|
8932
10655
|
currentTime,
|
|
8933
10656
|
currentSlot,
|
|
8934
10657
|
inputTokenInfo,
|
|
8935
|
-
outputTokenInfo
|
|
10658
|
+
outputTokenInfo,
|
|
10659
|
+
tokenADecimal,
|
|
10660
|
+
tokenBDecimal,
|
|
10661
|
+
hasReferral
|
|
8936
10662
|
} = params;
|
|
8937
|
-
const {
|
|
8938
|
-
sqrtPrice: sqrtPriceQ64,
|
|
8939
|
-
liquidity: liquidityQ64,
|
|
8940
|
-
activationType,
|
|
8941
|
-
activationPoint,
|
|
8942
|
-
collectFeeMode,
|
|
8943
|
-
poolFees
|
|
8944
|
-
} = poolState;
|
|
8945
|
-
const {
|
|
8946
|
-
feeSchedulerMode,
|
|
8947
|
-
cliffFeeNumerator,
|
|
8948
|
-
numberOfPeriod,
|
|
8949
|
-
reductionFactor,
|
|
8950
|
-
periodFrequency
|
|
8951
|
-
} = poolFees.baseFee;
|
|
8952
|
-
const dynamicFee = poolFees.dynamicFee;
|
|
8953
|
-
let actualAmountIn = inAmount;
|
|
8954
|
-
if (inputTokenInfo) {
|
|
8955
|
-
actualAmountIn = calculateTransferFeeExcludedAmount(
|
|
8956
|
-
inAmount,
|
|
8957
|
-
inputTokenInfo.mint,
|
|
8958
|
-
inputTokenInfo.currentEpoch
|
|
8959
|
-
).amount;
|
|
8960
|
-
}
|
|
10663
|
+
const { activationType } = poolState;
|
|
8961
10664
|
const aToB = poolState.tokenAMint.equals(inputTokenMint);
|
|
8962
|
-
const currentPoint = activationType ? currentTime : currentSlot;
|
|
8963
|
-
|
|
8964
|
-
|
|
8965
|
-
const { volatilityAccumulator, binStep, variableFeeControl } = dynamicFee;
|
|
8966
|
-
dynamicFeeParams = { volatilityAccumulator, binStep, variableFeeControl };
|
|
8967
|
-
}
|
|
8968
|
-
const tradeFeeNumerator = getFeeNumerator(
|
|
10665
|
+
const currentPoint = activationType ? new BN16(currentTime) : new BN16(currentSlot);
|
|
10666
|
+
const swapResult = swapQuoteExactInput(
|
|
10667
|
+
poolState,
|
|
8969
10668
|
currentPoint,
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
periodFrequency,
|
|
8973
|
-
feeSchedulerMode,
|
|
8974
|
-
cliffFeeNumerator,
|
|
8975
|
-
reductionFactor,
|
|
8976
|
-
dynamicFeeParams
|
|
8977
|
-
);
|
|
8978
|
-
const { amountOut, totalFee, nextSqrtPrice } = getSwapAmount(
|
|
8979
|
-
actualAmountIn,
|
|
8980
|
-
sqrtPriceQ64,
|
|
8981
|
-
liquidityQ64,
|
|
8982
|
-
tradeFeeNumerator,
|
|
10669
|
+
inAmount,
|
|
10670
|
+
slippage,
|
|
8983
10671
|
aToB,
|
|
8984
|
-
|
|
8985
|
-
|
|
8986
|
-
|
|
8987
|
-
|
|
8988
|
-
|
|
8989
|
-
amountOut,
|
|
8990
|
-
outputTokenInfo.mint,
|
|
8991
|
-
outputTokenInfo.currentEpoch
|
|
8992
|
-
).amount;
|
|
8993
|
-
}
|
|
8994
|
-
const minSwapOutAmount = getMinAmountWithSlippage(
|
|
8995
|
-
actualAmountOut,
|
|
8996
|
-
slippage
|
|
10672
|
+
hasReferral,
|
|
10673
|
+
tokenADecimal,
|
|
10674
|
+
tokenBDecimal,
|
|
10675
|
+
inputTokenInfo,
|
|
10676
|
+
outputTokenInfo
|
|
8997
10677
|
);
|
|
8998
10678
|
return {
|
|
8999
10679
|
swapInAmount: inAmount,
|
|
9000
|
-
consumedInAmount:
|
|
9001
|
-
swapOutAmount:
|
|
9002
|
-
minSwapOutAmount,
|
|
9003
|
-
totalFee,
|
|
9004
|
-
priceImpact:
|
|
9005
|
-
actualAmountIn,
|
|
9006
|
-
actualAmountOut,
|
|
9007
|
-
sqrtPriceQ64,
|
|
9008
|
-
aToB,
|
|
9009
|
-
params.tokenADecimal,
|
|
9010
|
-
params.tokenBDecimal
|
|
9011
|
-
)
|
|
10680
|
+
consumedInAmount: swapResult.includedFeeInputAmount,
|
|
10681
|
+
swapOutAmount: swapResult.outputAmount,
|
|
10682
|
+
minSwapOutAmount: swapResult.minimumAmountOut,
|
|
10683
|
+
totalFee: swapResult.tradingFee.add(swapResult.protocolFee).add(swapResult.partnerFee).add(swapResult.referralFee),
|
|
10684
|
+
priceImpact: swapResult.priceImpact
|
|
9012
10685
|
};
|
|
9013
10686
|
}
|
|
9014
|
-
|
|
9015
|
-
* Calculates swap quote based on desired output amount and pool state.
|
|
9016
|
-
* @param params - Swap parameters including output amount, pool state, slippage, etc.
|
|
9017
|
-
* @returns Swap quote including required input amount, fees, and price impact.
|
|
9018
|
-
*/
|
|
9019
|
-
getQuoteExactOut(params) {
|
|
10687
|
+
getQuote2(params) {
|
|
9020
10688
|
const {
|
|
9021
|
-
|
|
9022
|
-
outputTokenMint,
|
|
10689
|
+
inputTokenMint,
|
|
9023
10690
|
slippage,
|
|
9024
10691
|
poolState,
|
|
9025
|
-
|
|
9026
|
-
currentSlot,
|
|
10692
|
+
currentPoint,
|
|
9027
10693
|
inputTokenInfo,
|
|
9028
|
-
outputTokenInfo
|
|
10694
|
+
outputTokenInfo,
|
|
10695
|
+
hasReferral,
|
|
10696
|
+
tokenADecimal,
|
|
10697
|
+
tokenBDecimal,
|
|
10698
|
+
swapMode
|
|
9029
10699
|
} = params;
|
|
9030
|
-
const
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
-
|
|
9037
|
-
|
|
9038
|
-
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
|
|
9042
|
-
|
|
9043
|
-
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
10700
|
+
const aToB = poolState.tokenAMint.equals(inputTokenMint);
|
|
10701
|
+
switch (swapMode) {
|
|
10702
|
+
case 0 /* ExactIn */:
|
|
10703
|
+
if ("amountIn" in params) {
|
|
10704
|
+
return swapQuoteExactInput(
|
|
10705
|
+
poolState,
|
|
10706
|
+
currentPoint,
|
|
10707
|
+
params.amountIn,
|
|
10708
|
+
slippage,
|
|
10709
|
+
aToB,
|
|
10710
|
+
hasReferral,
|
|
10711
|
+
tokenADecimal,
|
|
10712
|
+
tokenBDecimal,
|
|
10713
|
+
inputTokenInfo,
|
|
10714
|
+
outputTokenInfo
|
|
10715
|
+
);
|
|
10716
|
+
}
|
|
10717
|
+
throw new Error("amountIn is required for ExactIn swap mode");
|
|
10718
|
+
case 2 /* ExactOut */:
|
|
10719
|
+
if ("amountOut" in params) {
|
|
10720
|
+
return swapQuoteExactOutput(
|
|
10721
|
+
poolState,
|
|
10722
|
+
currentPoint,
|
|
10723
|
+
params.amountOut,
|
|
10724
|
+
slippage,
|
|
10725
|
+
aToB,
|
|
10726
|
+
hasReferral,
|
|
10727
|
+
tokenADecimal,
|
|
10728
|
+
tokenBDecimal,
|
|
10729
|
+
inputTokenInfo,
|
|
10730
|
+
outputTokenInfo
|
|
10731
|
+
);
|
|
10732
|
+
}
|
|
10733
|
+
throw new Error("outAmount is required for ExactOut swap mode");
|
|
10734
|
+
case 1 /* PartialFill */:
|
|
10735
|
+
if ("amountIn" in params) {
|
|
10736
|
+
return swapQuotePartialInput(
|
|
10737
|
+
poolState,
|
|
10738
|
+
currentPoint,
|
|
10739
|
+
params.amountIn,
|
|
10740
|
+
slippage,
|
|
10741
|
+
aToB,
|
|
10742
|
+
hasReferral,
|
|
10743
|
+
tokenADecimal,
|
|
10744
|
+
tokenBDecimal,
|
|
10745
|
+
inputTokenInfo,
|
|
10746
|
+
outputTokenInfo
|
|
10747
|
+
);
|
|
10748
|
+
}
|
|
10749
|
+
throw new Error("amountIn is required for PartialFill swap mode");
|
|
10750
|
+
default:
|
|
10751
|
+
throw new Error(`Unsupported swap mode: ${swapMode}`);
|
|
9068
10752
|
}
|
|
9069
|
-
const maxInputAmount = new BN10(
|
|
9070
|
-
Math.ceil(actualInputAmount.toNumber() * (1 + slippage / 100))
|
|
9071
|
-
);
|
|
9072
|
-
const priceImpact = getPriceImpact(
|
|
9073
|
-
actualInputAmount,
|
|
9074
|
-
actualAmountOut,
|
|
9075
|
-
sqrtPriceQ64,
|
|
9076
|
-
!bToA,
|
|
9077
|
-
// aToB is the opposite of bToA
|
|
9078
|
-
params.tokenADecimal,
|
|
9079
|
-
params.tokenBDecimal
|
|
9080
|
-
).toNumber();
|
|
9081
|
-
return {
|
|
9082
|
-
swapResult,
|
|
9083
|
-
inputAmount: actualInputAmount,
|
|
9084
|
-
maxInputAmount,
|
|
9085
|
-
priceImpact
|
|
9086
|
-
};
|
|
9087
10753
|
}
|
|
9088
10754
|
/**
|
|
9089
10755
|
* Calculates the deposit quote for liquidity pool.
|
|
@@ -9117,9 +10783,9 @@ var CpAmm = class {
|
|
|
9117
10783
|
maxSqrtPrice
|
|
9118
10784
|
),
|
|
9119
10785
|
rawAmount: (delta) => getAmountBFromLiquidityDelta(
|
|
9120
|
-
delta,
|
|
9121
|
-
sqrtPrice,
|
|
9122
10786
|
minSqrtPrice,
|
|
10787
|
+
sqrtPrice,
|
|
10788
|
+
delta,
|
|
9123
10789
|
0 /* Up */
|
|
9124
10790
|
)
|
|
9125
10791
|
} : {
|
|
@@ -9129,13 +10795,13 @@ var CpAmm = class {
|
|
|
9129
10795
|
sqrtPrice
|
|
9130
10796
|
),
|
|
9131
10797
|
rawAmount: (delta) => getAmountAFromLiquidityDelta(
|
|
9132
|
-
delta,
|
|
9133
10798
|
sqrtPrice,
|
|
9134
10799
|
maxSqrtPrice,
|
|
10800
|
+
delta,
|
|
9135
10801
|
0 /* Up */
|
|
9136
10802
|
)
|
|
9137
10803
|
};
|
|
9138
|
-
const rawOutputAmount = new
|
|
10804
|
+
const rawOutputAmount = new BN16(rawAmount(liquidityDelta));
|
|
9139
10805
|
const outputAmount = outputTokenInfo ? calculateTransferFeeIncludedAmount(
|
|
9140
10806
|
rawOutputAmount,
|
|
9141
10807
|
outputTokenInfo.mint,
|
|
@@ -9171,15 +10837,15 @@ var CpAmm = class {
|
|
|
9171
10837
|
tokenBTokenInfo
|
|
9172
10838
|
} = params;
|
|
9173
10839
|
const amountA = getAmountAFromLiquidityDelta(
|
|
9174
|
-
liquidityDelta,
|
|
9175
10840
|
sqrtPrice,
|
|
9176
10841
|
maxSqrtPrice,
|
|
10842
|
+
liquidityDelta,
|
|
9177
10843
|
1 /* Down */
|
|
9178
10844
|
);
|
|
9179
10845
|
const amountB = getAmountBFromLiquidityDelta(
|
|
9180
|
-
liquidityDelta,
|
|
9181
|
-
sqrtPrice,
|
|
9182
10846
|
minSqrtPrice,
|
|
10847
|
+
sqrtPrice,
|
|
10848
|
+
liquidityDelta,
|
|
9183
10849
|
1 /* Down */
|
|
9184
10850
|
);
|
|
9185
10851
|
return {
|
|
@@ -9242,7 +10908,7 @@ var CpAmm = class {
|
|
|
9242
10908
|
tokenAInfo,
|
|
9243
10909
|
tokenBInfo
|
|
9244
10910
|
} = params;
|
|
9245
|
-
if (tokenAAmount.eq(new
|
|
10911
|
+
if (tokenAAmount.eq(new BN16(0)) && tokenBAmount.eq(new BN16(0))) {
|
|
9246
10912
|
throw new Error("Invalid input amount");
|
|
9247
10913
|
}
|
|
9248
10914
|
const actualAmountAIn = tokenAInfo ? tokenAAmount.sub(
|
|
@@ -9409,7 +11075,7 @@ var CpAmm = class {
|
|
|
9409
11075
|
tokenAMint,
|
|
9410
11076
|
tokenBMint,
|
|
9411
11077
|
tokenAAmount,
|
|
9412
|
-
tokenBAmount: tokenBMint.equals(NATIVE_MINT2) ? max(tokenBAmount, new
|
|
11078
|
+
tokenBAmount: tokenBMint.equals(NATIVE_MINT2) ? max(tokenBAmount, new BN16(1)) : tokenBAmount,
|
|
9413
11079
|
payer,
|
|
9414
11080
|
positionNft,
|
|
9415
11081
|
tokenAProgram,
|
|
@@ -9921,6 +11587,7 @@ var CpAmm = class {
|
|
|
9921
11587
|
const [inputTokenProgram, outputTokenProgram] = inputTokenMint.equals(
|
|
9922
11588
|
tokenAMint
|
|
9923
11589
|
) ? [tokenAProgram, tokenBProgram] : [tokenBProgram, tokenAProgram];
|
|
11590
|
+
const tradeDirection = inputTokenMint.equals(tokenAMint) ? 0 /* AtoB */ : 1 /* BtoA */;
|
|
9924
11591
|
const {
|
|
9925
11592
|
tokenAAta: inputTokenAccount,
|
|
9926
11593
|
tokenBAta: outputTokenAccount,
|
|
@@ -9949,6 +11616,30 @@ var CpAmm = class {
|
|
|
9949
11616
|
const closeWrappedSOLIx = yield unwrapSOLInstruction(payer);
|
|
9950
11617
|
closeWrappedSOLIx && postInstructions.push(closeWrappedSOLIx);
|
|
9951
11618
|
}
|
|
11619
|
+
const poolState = yield this.fetchPoolState(pool);
|
|
11620
|
+
const currentPoint = yield getCurrentPoint(
|
|
11621
|
+
this._program.provider.connection,
|
|
11622
|
+
poolState.activationType
|
|
11623
|
+
);
|
|
11624
|
+
const { maxLimiterDuration, maxFeeBps } = parseRateLimiterSecondFactor(
|
|
11625
|
+
poolState.poolFees.baseFee.secondFactor
|
|
11626
|
+
);
|
|
11627
|
+
const rateLimiterApplied = isRateLimiterApplied(
|
|
11628
|
+
poolState.poolFees.baseFee.thirdFactor,
|
|
11629
|
+
maxLimiterDuration,
|
|
11630
|
+
maxFeeBps,
|
|
11631
|
+
poolState.poolFees.baseFee.firstFactor,
|
|
11632
|
+
currentPoint,
|
|
11633
|
+
poolState.activationPoint,
|
|
11634
|
+
tradeDirection
|
|
11635
|
+
);
|
|
11636
|
+
const remainingAccounts = rateLimiterApplied ? [
|
|
11637
|
+
{
|
|
11638
|
+
isSigner: false,
|
|
11639
|
+
isWritable: false,
|
|
11640
|
+
pubkey: SYSVAR_INSTRUCTIONS_PUBKEY
|
|
11641
|
+
}
|
|
11642
|
+
] : [];
|
|
9952
11643
|
return yield this._program.methods.swap({
|
|
9953
11644
|
amountIn,
|
|
9954
11645
|
minimumAmountOut
|
|
@@ -9965,7 +11656,109 @@ var CpAmm = class {
|
|
|
9965
11656
|
tokenAProgram,
|
|
9966
11657
|
tokenBProgram,
|
|
9967
11658
|
referralTokenAccount
|
|
9968
|
-
}).preInstructions(preInstructions).postInstructions(postInstructions).transaction();
|
|
11659
|
+
}).remainingAccounts(remainingAccounts).preInstructions(preInstructions).postInstructions(postInstructions).transaction();
|
|
11660
|
+
});
|
|
11661
|
+
}
|
|
11662
|
+
swap2(params) {
|
|
11663
|
+
return __async(this, null, function* () {
|
|
11664
|
+
const {
|
|
11665
|
+
payer,
|
|
11666
|
+
pool,
|
|
11667
|
+
inputTokenMint,
|
|
11668
|
+
outputTokenMint,
|
|
11669
|
+
tokenAVault,
|
|
11670
|
+
tokenBVault,
|
|
11671
|
+
tokenAMint,
|
|
11672
|
+
tokenBMint,
|
|
11673
|
+
tokenAProgram,
|
|
11674
|
+
tokenBProgram,
|
|
11675
|
+
referralTokenAccount,
|
|
11676
|
+
swapMode
|
|
11677
|
+
} = params;
|
|
11678
|
+
const [inputTokenProgram, outputTokenProgram] = inputTokenMint.equals(
|
|
11679
|
+
tokenAMint
|
|
11680
|
+
) ? [tokenAProgram, tokenBProgram] : [tokenBProgram, tokenAProgram];
|
|
11681
|
+
const tradeDirection = inputTokenMint.equals(tokenAMint) ? 0 /* AtoB */ : 1 /* BtoA */;
|
|
11682
|
+
const {
|
|
11683
|
+
tokenAAta: inputTokenAccount,
|
|
11684
|
+
tokenBAta: outputTokenAccount,
|
|
11685
|
+
instructions: preInstructions
|
|
11686
|
+
} = yield this.prepareTokenAccounts({
|
|
11687
|
+
payer,
|
|
11688
|
+
tokenAOwner: payer,
|
|
11689
|
+
tokenBOwner: payer,
|
|
11690
|
+
tokenAMint: inputTokenMint,
|
|
11691
|
+
tokenBMint: outputTokenMint,
|
|
11692
|
+
tokenAProgram: inputTokenProgram,
|
|
11693
|
+
tokenBProgram: outputTokenProgram
|
|
11694
|
+
});
|
|
11695
|
+
let amount0;
|
|
11696
|
+
let amount1;
|
|
11697
|
+
if (swapMode === 2 /* ExactOut */) {
|
|
11698
|
+
amount0 = params.amountOut;
|
|
11699
|
+
amount1 = params.maximumAmountIn;
|
|
11700
|
+
} else {
|
|
11701
|
+
amount0 = params.amountIn;
|
|
11702
|
+
amount1 = params.minimumAmountOut;
|
|
11703
|
+
}
|
|
11704
|
+
if (inputTokenMint.equals(NATIVE_MINT2)) {
|
|
11705
|
+
const amount = swapMode === 0 /* ExactIn */ || swapMode === 1 /* PartialFill */ ? amount0 : amount1;
|
|
11706
|
+
const wrapSOLIx = wrapSOLInstruction(
|
|
11707
|
+
payer,
|
|
11708
|
+
inputTokenAccount,
|
|
11709
|
+
BigInt(amount.toString())
|
|
11710
|
+
);
|
|
11711
|
+
preInstructions.push(...wrapSOLIx);
|
|
11712
|
+
}
|
|
11713
|
+
const postInstructions = [];
|
|
11714
|
+
if ([tokenAMint.toBase58(), tokenBMint.toBase58()].includes(
|
|
11715
|
+
NATIVE_MINT2.toBase58()
|
|
11716
|
+
)) {
|
|
11717
|
+
const closeWrappedSOLIx = yield unwrapSOLInstruction(payer);
|
|
11718
|
+
closeWrappedSOLIx && postInstructions.push(closeWrappedSOLIx);
|
|
11719
|
+
}
|
|
11720
|
+
const poolState = yield this.fetchPoolState(pool);
|
|
11721
|
+
const currentPoint = yield getCurrentPoint(
|
|
11722
|
+
this._program.provider.connection,
|
|
11723
|
+
poolState.activationType
|
|
11724
|
+
);
|
|
11725
|
+
const { maxLimiterDuration, maxFeeBps } = parseRateLimiterSecondFactor(
|
|
11726
|
+
poolState.poolFees.baseFee.secondFactor
|
|
11727
|
+
);
|
|
11728
|
+
const rateLimiterApplied = isRateLimiterApplied(
|
|
11729
|
+
poolState.poolFees.baseFee.thirdFactor,
|
|
11730
|
+
maxLimiterDuration,
|
|
11731
|
+
maxFeeBps,
|
|
11732
|
+
poolState.poolFees.baseFee.firstFactor,
|
|
11733
|
+
currentPoint,
|
|
11734
|
+
poolState.activationPoint,
|
|
11735
|
+
tradeDirection
|
|
11736
|
+
);
|
|
11737
|
+
const remainingAccounts = rateLimiterApplied ? [
|
|
11738
|
+
{
|
|
11739
|
+
isSigner: false,
|
|
11740
|
+
isWritable: false,
|
|
11741
|
+
pubkey: SYSVAR_INSTRUCTIONS_PUBKEY
|
|
11742
|
+
}
|
|
11743
|
+
] : [];
|
|
11744
|
+
return yield this._program.methods.swap2({
|
|
11745
|
+
amount0,
|
|
11746
|
+
amount1,
|
|
11747
|
+
swapMode
|
|
11748
|
+
}).accountsPartial({
|
|
11749
|
+
poolAuthority: this.poolAuthority,
|
|
11750
|
+
pool,
|
|
11751
|
+
payer,
|
|
11752
|
+
inputTokenAccount,
|
|
11753
|
+
outputTokenAccount,
|
|
11754
|
+
tokenAVault,
|
|
11755
|
+
tokenBVault,
|
|
11756
|
+
tokenAMint,
|
|
11757
|
+
tokenBMint,
|
|
11758
|
+
tokenAProgram,
|
|
11759
|
+
tokenBProgram,
|
|
11760
|
+
referralTokenAccount
|
|
11761
|
+
}).remainingAccounts(remainingAccounts).preInstructions(preInstructions).postInstructions(postInstructions).transaction();
|
|
9969
11762
|
});
|
|
9970
11763
|
}
|
|
9971
11764
|
/**
|
|
@@ -10199,7 +11992,7 @@ var CpAmm = class {
|
|
|
10199
11992
|
);
|
|
10200
11993
|
return total.add(available);
|
|
10201
11994
|
},
|
|
10202
|
-
new
|
|
11995
|
+
new BN16(0)
|
|
10203
11996
|
);
|
|
10204
11997
|
positionBLiquidityDelta = positionBLiquidityDelta.add(
|
|
10205
11998
|
totalAvailableVestingLiquidity
|
|
@@ -10214,15 +12007,15 @@ var CpAmm = class {
|
|
|
10214
12007
|
refreshVestingInstruction && preInstructions.push(refreshVestingInstruction);
|
|
10215
12008
|
}
|
|
10216
12009
|
const tokenAWithdrawAmount = getAmountAFromLiquidityDelta(
|
|
10217
|
-
positionBLiquidityDelta,
|
|
10218
12010
|
poolState.sqrtPrice,
|
|
10219
12011
|
poolState.sqrtMaxPrice,
|
|
12012
|
+
positionBLiquidityDelta,
|
|
10220
12013
|
1 /* Down */
|
|
10221
12014
|
);
|
|
10222
12015
|
const tokenBWithdrawAmount = getAmountBFromLiquidityDelta(
|
|
10223
|
-
positionBLiquidityDelta,
|
|
10224
|
-
poolState.sqrtPrice,
|
|
10225
12016
|
poolState.sqrtMinPrice,
|
|
12017
|
+
poolState.sqrtPrice,
|
|
12018
|
+
positionBLiquidityDelta,
|
|
10226
12019
|
1 /* Down */
|
|
10227
12020
|
);
|
|
10228
12021
|
const newLiquidityDelta = this.getLiquidityDelta({
|
|
@@ -10679,30 +12472,59 @@ export {
|
|
|
10679
12472
|
BASIS_POINT_MAX,
|
|
10680
12473
|
BIN_STEP_BPS_DEFAULT,
|
|
10681
12474
|
BIN_STEP_BPS_U128_DEFAULT,
|
|
12475
|
+
BaseFeeMode,
|
|
10682
12476
|
CP_AMM_PROGRAM_ID,
|
|
12477
|
+
CURRENT_POOL_VERSION,
|
|
10683
12478
|
CollectFeeMode,
|
|
10684
12479
|
CpAmm,
|
|
10685
12480
|
DYNAMIC_FEE_DECAY_PERIOD_DEFAULT,
|
|
10686
12481
|
DYNAMIC_FEE_FILTER_PERIOD_DEFAULT,
|
|
10687
12482
|
DYNAMIC_FEE_REDUCTION_FACTOR_DEFAULT,
|
|
12483
|
+
DYNAMIC_FEE_ROUNDING_OFFSET,
|
|
12484
|
+
DYNAMIC_FEE_SCALING_FACTOR,
|
|
10688
12485
|
FEE_DENOMINATOR,
|
|
10689
|
-
|
|
12486
|
+
FeeRateLimiter,
|
|
12487
|
+
FeeScheduler,
|
|
10690
12488
|
LIQUIDITY_SCALE,
|
|
12489
|
+
MAX,
|
|
10691
12490
|
MAX_CU_BUFFER,
|
|
10692
|
-
|
|
12491
|
+
MAX_EXPONENTIAL,
|
|
12492
|
+
MAX_FEE_BPS_V0,
|
|
12493
|
+
MAX_FEE_BPS_V1,
|
|
12494
|
+
MAX_FEE_NUMERATOR_V0,
|
|
12495
|
+
MAX_FEE_NUMERATOR_V1,
|
|
10693
12496
|
MAX_PRICE_CHANGE_BPS_DEFAULT,
|
|
12497
|
+
MAX_RATE_LIMITER_DURATION_IN_SECONDS,
|
|
12498
|
+
MAX_RATE_LIMITER_DURATION_IN_SLOTS,
|
|
10694
12499
|
MAX_SQRT_PRICE,
|
|
10695
12500
|
MIN_CU_BUFFER,
|
|
12501
|
+
MIN_FEE_BPS,
|
|
12502
|
+
MIN_FEE_NUMERATOR,
|
|
10696
12503
|
MIN_SQRT_PRICE,
|
|
10697
|
-
|
|
12504
|
+
ONE_Q64,
|
|
12505
|
+
PoolStatus,
|
|
12506
|
+
PoolVersion,
|
|
10698
12507
|
Rounding,
|
|
10699
12508
|
SCALE_OFFSET,
|
|
10700
12509
|
SPLIT_POSITION_DENOMINATOR,
|
|
12510
|
+
SwapMode,
|
|
10701
12511
|
TradeDirection,
|
|
12512
|
+
U128_MAX,
|
|
12513
|
+
U16_MAX,
|
|
12514
|
+
U64_MAX,
|
|
10702
12515
|
bpsToFeeNumerator,
|
|
12516
|
+
calculateAtoBFromAmountIn,
|
|
12517
|
+
calculateAtoBFromAmountOut,
|
|
12518
|
+
calculateAtoBFromPartialAmountIn,
|
|
12519
|
+
calculateBtoAFromAmountIn,
|
|
12520
|
+
calculateBtoAFromAmountOut,
|
|
12521
|
+
calculateBtoAFromPartialAmountIn,
|
|
10703
12522
|
calculateInitSqrtPrice,
|
|
10704
12523
|
calculateTransferFeeExcludedAmount,
|
|
10705
12524
|
calculateTransferFeeIncludedAmount,
|
|
12525
|
+
convertToFeeSchedulerSecondFactor,
|
|
12526
|
+
convertToLamports,
|
|
12527
|
+
convertToRateLimiterSecondFactor,
|
|
10706
12528
|
decimalToQ64,
|
|
10707
12529
|
index_default as default,
|
|
10708
12530
|
deriveClaimFeeOperatorAddress,
|
|
@@ -10716,49 +12538,90 @@ export {
|
|
|
10716
12538
|
deriveTokenBadgeAddress,
|
|
10717
12539
|
deriveTokenVaultAddress,
|
|
10718
12540
|
feeNumeratorToBps,
|
|
12541
|
+
fromDecimalToBN,
|
|
10719
12542
|
getAllPositionNftAccountByOwner,
|
|
10720
12543
|
getAllUserPositionNftAccount,
|
|
10721
12544
|
getAmountAFromLiquidityDelta,
|
|
10722
12545
|
getAmountBFromLiquidityDelta,
|
|
12546
|
+
getAmountWithSlippage,
|
|
10723
12547
|
getAvailableVestingLiquidity,
|
|
12548
|
+
getBaseFeeHandler,
|
|
10724
12549
|
getBaseFeeNumerator,
|
|
12550
|
+
getBaseFeeNumeratorByPeriod,
|
|
10725
12551
|
getBaseFeeParams,
|
|
12552
|
+
getCheckedAmounts,
|
|
12553
|
+
getCurrentPoint,
|
|
10726
12554
|
getDynamicFeeNumerator,
|
|
10727
12555
|
getDynamicFeeParams,
|
|
10728
12556
|
getEstimatedComputeUnitIxWithBuffer,
|
|
10729
12557
|
getEstimatedComputeUnitUsageWithBuffer,
|
|
10730
12558
|
getExcludedFeeAmount,
|
|
12559
|
+
getExcludedFeeAmountFromIncludedFeeAmount,
|
|
12560
|
+
getFeeInPeriod,
|
|
10731
12561
|
getFeeMode,
|
|
10732
|
-
|
|
12562
|
+
getFeeNumeratorFromExcludedFeeAmount,
|
|
12563
|
+
getFeeNumeratorFromIncludedFeeAmount,
|
|
12564
|
+
getFeeNumeratorOnExponentialFeeScheduler,
|
|
12565
|
+
getFeeNumeratorOnLinearFeeScheduler,
|
|
12566
|
+
getFeeOnAmount,
|
|
12567
|
+
getFeeSchedulerParams,
|
|
10733
12568
|
getFirstKey,
|
|
10734
12569
|
getIncludedFeeAmount,
|
|
10735
12570
|
getLiquidityDeltaFromAmountA,
|
|
10736
12571
|
getLiquidityDeltaFromAmountB,
|
|
10737
12572
|
getMaxAmountWithSlippage,
|
|
10738
|
-
|
|
10739
|
-
|
|
10740
|
-
|
|
10741
|
-
|
|
12573
|
+
getMaxBaseFeeNumerator,
|
|
12574
|
+
getMaxFeeBps,
|
|
12575
|
+
getMaxFeeNumerator,
|
|
12576
|
+
getMaxIndex,
|
|
12577
|
+
getMinBaseFeeNumerator,
|
|
12578
|
+
getNextSqrtPriceFromAmountInARoundingUp,
|
|
12579
|
+
getNextSqrtPriceFromAmountInBRoundingDown,
|
|
12580
|
+
getNextSqrtPriceFromAmountOutARoundingUp,
|
|
12581
|
+
getNextSqrtPriceFromAmountOutBRoundingDown,
|
|
12582
|
+
getNextSqrtPriceFromInput,
|
|
10742
12583
|
getNextSqrtPriceFromOutput,
|
|
10743
12584
|
getOrCreateATAInstruction,
|
|
10744
12585
|
getPriceChange,
|
|
10745
12586
|
getPriceFromSqrtPrice,
|
|
10746
12587
|
getPriceImpact,
|
|
12588
|
+
getRateLimiterParams,
|
|
10747
12589
|
getSecondKey,
|
|
10748
12590
|
getSimulationComputeUnits,
|
|
10749
12591
|
getSqrtPriceFromPrice,
|
|
10750
|
-
|
|
10751
|
-
|
|
12592
|
+
getSwapResultFromExactInput,
|
|
12593
|
+
getSwapResultFromExactOutput,
|
|
12594
|
+
getSwapResultFromPartialInput,
|
|
10752
12595
|
getTokenDecimals,
|
|
10753
12596
|
getTokenProgram,
|
|
12597
|
+
getTotalFeeNumerator,
|
|
10754
12598
|
getTotalLockedLiquidity,
|
|
12599
|
+
getTotalTradingFeeFromExcludedFeeAmount,
|
|
12600
|
+
getTotalTradingFeeFromIncludedFeeAmount,
|
|
10755
12601
|
getUnClaimReward,
|
|
12602
|
+
hasPartner,
|
|
12603
|
+
isDynamicFeeEnabled,
|
|
12604
|
+
isNonZeroRateLimiter,
|
|
12605
|
+
isRateLimiterApplied,
|
|
12606
|
+
isSwapEnabled,
|
|
10756
12607
|
isVestingComplete,
|
|
12608
|
+
isZeroRateLimiter,
|
|
10757
12609
|
mulDiv,
|
|
12610
|
+
parseFeeSchedulerSecondFactor,
|
|
12611
|
+
parseRateLimiterSecondFactor,
|
|
10758
12612
|
positionByPoolFilter,
|
|
10759
12613
|
pow,
|
|
10760
12614
|
q64ToDecimal,
|
|
12615
|
+
splitFees,
|
|
12616
|
+
sqrt,
|
|
12617
|
+
swapQuoteExactInput,
|
|
12618
|
+
swapQuoteExactOutput,
|
|
12619
|
+
swapQuotePartialInput,
|
|
12620
|
+
toNumerator,
|
|
10761
12621
|
unwrapSOLInstruction,
|
|
12622
|
+
validateFeeFraction,
|
|
12623
|
+
validateFeeRateLimiter,
|
|
12624
|
+
validateFeeScheduler,
|
|
10762
12625
|
vestingByPositionFilter,
|
|
10763
12626
|
wrapSOLInstruction
|
|
10764
12627
|
};
|