@jup-ag/lend 0.2.0-beta.1 → 0.2.0-beta.3

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.
@@ -1,8 +1,7 @@
1
- import { PublicKey, Transaction, SYSVAR_RENT_PUBKEY, SYSVAR_INSTRUCTIONS_PUBKEY, SystemProgram } from '@solana/web3.js';
2
- import BN from 'bn.js';
3
1
  import { Program, AnchorProvider } from '@coral-xyz/anchor';
4
- import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, getAssociatedTokenAddressSync, NATIVE_MINT } from '@solana/spl-token';
5
- import { a as getTickHasDebt, c as getPosition, d as getTick, e as getTickIdLiquidation, f as getVaultConfig, h as getBranch, i as getVaultState, j as getPositionMetadata, k as getPositionTokenAccount, l as getPositionMint, g as getVaultAdmin, m as getVaultMetadata, n as getLiquidity, o as getClaimAccount, p as getRateModel, q as getUserBorrowPosition, r as getUserSupplyPosition, s as getLiquidityReserve } from './lend.ByiEG4eI.mjs';
2
+ import BN from 'bn.js';
3
+ import { p as getTickHasDebt, e as getPosition, q as getTick, s as getTickIdLiquidation, i as getVaultMetadata, h as getVaultConfig, r as getBranch, f as getVaultState } from './lend.a53XYkl5.mjs';
4
+ import { PublicKey, Transaction } from '@solana/web3.js';
6
5
  import { e as getReserve } from './lend.C3XdrR6R.mjs';
7
6
 
8
7
  const address$1 = "jupnw4B6Eqs7ft6rxpzYLJZYSnrpRgPcr589n5Kv4oc";
@@ -895,6 +894,26 @@ const errors$1 = [
895
894
  code: 6044,
896
895
  name: "ChainlinkDataStreamsNoFeedKeepers",
897
896
  msg: "CHAINLINK_DATA_STREAMS_NO_FEED_KEEPERS"
897
+ },
898
+ {
899
+ code: 6045,
900
+ name: "PstPoolInvalidState",
901
+ msg: "PST_POOL_INVALID_STATE"
902
+ },
903
+ {
904
+ code: 6046,
905
+ name: "PstPoolModeStatesEmpty",
906
+ msg: "PST_POOL_MODE_STATES_EMPTY"
907
+ },
908
+ {
909
+ code: 6047,
910
+ name: "PstPoolMintMismatch",
911
+ msg: "PST_POOL_MINT_MISMATCH"
912
+ },
913
+ {
914
+ code: 6048,
915
+ name: "PstPoolMintSupplyZero",
916
+ msg: "PST_POOL_MINT_SUPPLY_ZERO"
898
917
  }
899
918
  ];
900
919
  const types$1 = [
@@ -1288,6 +1307,9 @@ const types$1 = [
1288
1307
  },
1289
1308
  {
1290
1309
  name: "ChainlinkDataStreams"
1310
+ },
1311
+ {
1312
+ name: "PstPool"
1291
1313
  }
1292
1314
  ]
1293
1315
  }
@@ -1432,7 +1454,7 @@ function mulShift64(n0, n1) {
1432
1454
  }
1433
1455
  function getTickAtRatio(ratioX48) {
1434
1456
  const MIN_RATIOX48 = new BN(6093);
1435
- const MAX_RATIOX48 = new BN("13002088133096036565414295");
1457
+ const MAX_RATIOX48 = new BN("13002088162051014298412982");
1436
1458
  const _1E13 = new BN("10000000000000");
1437
1459
  if (ratioX48.lt(MIN_RATIOX48) || ratioX48.gt(MAX_RATIOX48)) {
1438
1460
  throw new Error(`Ratio ${ratioX48.toString()} out of bounds`);
@@ -2555,120 +2577,14 @@ const instructions = [
2555
2577
  },
2556
2578
  {
2557
2579
  name: "signer_token_account",
2558
- writable: true,
2559
- pda: {
2560
- seeds: [
2561
- {
2562
- kind: "account",
2563
- path: "signer"
2564
- },
2565
- {
2566
- kind: "account",
2567
- path: "borrow_token_program"
2568
- },
2569
- {
2570
- kind: "account",
2571
- path: "borrow_token"
2572
- }
2573
- ],
2574
- program: {
2575
- kind: "const",
2576
- value: [
2577
- 140,
2578
- 151,
2579
- 37,
2580
- 143,
2581
- 78,
2582
- 36,
2583
- 137,
2584
- 241,
2585
- 187,
2586
- 61,
2587
- 16,
2588
- 41,
2589
- 20,
2590
- 142,
2591
- 13,
2592
- 131,
2593
- 11,
2594
- 90,
2595
- 19,
2596
- 153,
2597
- 218,
2598
- 255,
2599
- 16,
2600
- 132,
2601
- 4,
2602
- 142,
2603
- 123,
2604
- 216,
2605
- 219,
2606
- 233,
2607
- 248,
2608
- 89
2609
- ]
2610
- }
2611
- }
2580
+ writable: true
2612
2581
  },
2613
2582
  {
2614
2583
  name: "to"
2615
2584
  },
2616
2585
  {
2617
2586
  name: "to_token_account",
2618
- writable: true,
2619
- pda: {
2620
- seeds: [
2621
- {
2622
- kind: "account",
2623
- path: "to"
2624
- },
2625
- {
2626
- kind: "account",
2627
- path: "supply_token_program"
2628
- },
2629
- {
2630
- kind: "account",
2631
- path: "supply_token"
2632
- }
2633
- ],
2634
- program: {
2635
- kind: "const",
2636
- value: [
2637
- 140,
2638
- 151,
2639
- 37,
2640
- 143,
2641
- 78,
2642
- 36,
2643
- 137,
2644
- 241,
2645
- 187,
2646
- 61,
2647
- 16,
2648
- 41,
2649
- 20,
2650
- 142,
2651
- 13,
2652
- 131,
2653
- 11,
2654
- 90,
2655
- 19,
2656
- 153,
2657
- 218,
2658
- 255,
2659
- 16,
2660
- 132,
2661
- 4,
2662
- 142,
2663
- 123,
2664
- 216,
2665
- 219,
2666
- 233,
2667
- 248,
2668
- 89
2669
- ]
2670
- }
2671
- }
2587
+ writable: true
2672
2588
  },
2673
2589
  {
2674
2590
  name: "vault_config",
@@ -2747,6 +2663,7 @@ const instructions = [
2747
2663
  },
2748
2664
  {
2749
2665
  name: "associated_token_program",
2666
+ optional: true,
2750
2667
  address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
2751
2668
  },
2752
2669
  {
@@ -2802,117 +2719,11 @@ const instructions = [
2802
2719
  },
2803
2720
  {
2804
2721
  name: "signer_supply_token_account",
2805
- writable: true,
2806
- pda: {
2807
- seeds: [
2808
- {
2809
- kind: "account",
2810
- path: "signer"
2811
- },
2812
- {
2813
- kind: "account",
2814
- path: "supply_token_program"
2815
- },
2816
- {
2817
- kind: "account",
2818
- path: "supply_token"
2819
- }
2820
- ],
2821
- program: {
2822
- kind: "const",
2823
- value: [
2824
- 140,
2825
- 151,
2826
- 37,
2827
- 143,
2828
- 78,
2829
- 36,
2830
- 137,
2831
- 241,
2832
- 187,
2833
- 61,
2834
- 16,
2835
- 41,
2836
- 20,
2837
- 142,
2838
- 13,
2839
- 131,
2840
- 11,
2841
- 90,
2842
- 19,
2843
- 153,
2844
- 218,
2845
- 255,
2846
- 16,
2847
- 132,
2848
- 4,
2849
- 142,
2850
- 123,
2851
- 216,
2852
- 219,
2853
- 233,
2854
- 248,
2855
- 89
2856
- ]
2857
- }
2858
- }
2722
+ writable: true
2859
2723
  },
2860
2724
  {
2861
2725
  name: "signer_borrow_token_account",
2862
- writable: true,
2863
- pda: {
2864
- seeds: [
2865
- {
2866
- kind: "account",
2867
- path: "signer"
2868
- },
2869
- {
2870
- kind: "account",
2871
- path: "borrow_token_program"
2872
- },
2873
- {
2874
- kind: "account",
2875
- path: "borrow_token"
2876
- }
2877
- ],
2878
- program: {
2879
- kind: "const",
2880
- value: [
2881
- 140,
2882
- 151,
2883
- 37,
2884
- 143,
2885
- 78,
2886
- 36,
2887
- 137,
2888
- 241,
2889
- 187,
2890
- 61,
2891
- 16,
2892
- 41,
2893
- 20,
2894
- 142,
2895
- 13,
2896
- 131,
2897
- 11,
2898
- 90,
2899
- 19,
2900
- 153,
2901
- 218,
2902
- 255,
2903
- 16,
2904
- 132,
2905
- 4,
2906
- 142,
2907
- 123,
2908
- 216,
2909
- 219,
2910
- 233,
2911
- 248,
2912
- 89
2913
- ]
2914
- }
2915
- }
2726
+ writable: true
2916
2727
  },
2917
2728
  {
2918
2729
  name: "recipient",
@@ -2921,118 +2732,12 @@ const instructions = [
2921
2732
  {
2922
2733
  name: "recipient_borrow_token_account",
2923
2734
  writable: true,
2924
- optional: true,
2925
- pda: {
2926
- seeds: [
2927
- {
2928
- kind: "account",
2929
- path: "recipient"
2930
- },
2931
- {
2932
- kind: "account",
2933
- path: "borrow_token_program"
2934
- },
2935
- {
2936
- kind: "account",
2937
- path: "borrow_token"
2938
- }
2939
- ],
2940
- program: {
2941
- kind: "const",
2942
- value: [
2943
- 140,
2944
- 151,
2945
- 37,
2946
- 143,
2947
- 78,
2948
- 36,
2949
- 137,
2950
- 241,
2951
- 187,
2952
- 61,
2953
- 16,
2954
- 41,
2955
- 20,
2956
- 142,
2957
- 13,
2958
- 131,
2959
- 11,
2960
- 90,
2961
- 19,
2962
- 153,
2963
- 218,
2964
- 255,
2965
- 16,
2966
- 132,
2967
- 4,
2968
- 142,
2969
- 123,
2970
- 216,
2971
- 219,
2972
- 233,
2973
- 248,
2974
- 89
2975
- ]
2976
- }
2977
- }
2735
+ optional: true
2978
2736
  },
2979
2737
  {
2980
2738
  name: "recipient_supply_token_account",
2981
2739
  writable: true,
2982
- optional: true,
2983
- pda: {
2984
- seeds: [
2985
- {
2986
- kind: "account",
2987
- path: "recipient"
2988
- },
2989
- {
2990
- kind: "account",
2991
- path: "supply_token_program"
2992
- },
2993
- {
2994
- kind: "account",
2995
- path: "supply_token"
2996
- }
2997
- ],
2998
- program: {
2999
- kind: "const",
3000
- value: [
3001
- 140,
3002
- 151,
3003
- 37,
3004
- 143,
3005
- 78,
3006
- 36,
3007
- 137,
3008
- 241,
3009
- 187,
3010
- 61,
3011
- 16,
3012
- 41,
3013
- 20,
3014
- 142,
3015
- 13,
3016
- 131,
3017
- 11,
3018
- 90,
3019
- 19,
3020
- 153,
3021
- 218,
3022
- 255,
3023
- 16,
3024
- 132,
3025
- 4,
3026
- 142,
3027
- 123,
3028
- 216,
3029
- 219,
3030
- 233,
3031
- 248,
3032
- 89
3033
- ]
3034
- }
3035
- }
2740
+ optional: true
3036
2741
  },
3037
2742
  {
3038
2743
  name: "vault_config",
@@ -3143,6 +2848,7 @@ const instructions = [
3143
2848
  },
3144
2849
  {
3145
2850
  name: "associated_token_program",
2851
+ optional: true,
3146
2852
  address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
3147
2853
  },
3148
2854
  {
@@ -3198,117 +2904,11 @@ const instructions = [
3198
2904
  },
3199
2905
  {
3200
2906
  name: "rebalancer_supply_token_account",
3201
- writable: true,
3202
- pda: {
3203
- seeds: [
3204
- {
3205
- kind: "account",
3206
- path: "rebalancer"
3207
- },
3208
- {
3209
- kind: "account",
3210
- path: "supply_token_program"
3211
- },
3212
- {
3213
- kind: "account",
3214
- path: "supply_token"
3215
- }
3216
- ],
3217
- program: {
3218
- kind: "const",
3219
- value: [
3220
- 140,
3221
- 151,
3222
- 37,
3223
- 143,
3224
- 78,
3225
- 36,
3226
- 137,
3227
- 241,
3228
- 187,
3229
- 61,
3230
- 16,
3231
- 41,
3232
- 20,
3233
- 142,
3234
- 13,
3235
- 131,
3236
- 11,
3237
- 90,
3238
- 19,
3239
- 153,
3240
- 218,
3241
- 255,
3242
- 16,
3243
- 132,
3244
- 4,
3245
- 142,
3246
- 123,
3247
- 216,
3248
- 219,
3249
- 233,
3250
- 248,
3251
- 89
3252
- ]
3253
- }
3254
- }
2907
+ writable: true
3255
2908
  },
3256
2909
  {
3257
2910
  name: "rebalancer_borrow_token_account",
3258
- writable: true,
3259
- pda: {
3260
- seeds: [
3261
- {
3262
- kind: "account",
3263
- path: "rebalancer"
3264
- },
3265
- {
3266
- kind: "account",
3267
- path: "borrow_token_program"
3268
- },
3269
- {
3270
- kind: "account",
3271
- path: "borrow_token"
3272
- }
3273
- ],
3274
- program: {
3275
- kind: "const",
3276
- value: [
3277
- 140,
3278
- 151,
3279
- 37,
3280
- 143,
3281
- 78,
3282
- 36,
3283
- 137,
3284
- 241,
3285
- 187,
3286
- 61,
3287
- 16,
3288
- 41,
3289
- 20,
3290
- 142,
3291
- 13,
3292
- 131,
3293
- 11,
3294
- 90,
3295
- 19,
3296
- 153,
3297
- 218,
3298
- 255,
3299
- 16,
3300
- 132,
3301
- 4,
3302
- 142,
3303
- 123,
3304
- 216,
3305
- 219,
3306
- 233,
3307
- 248,
3308
- 89
3309
- ]
3310
- }
3311
- }
2911
+ writable: true
3312
2912
  },
3313
2913
  {
3314
2914
  name: "vault_config",
@@ -3385,6 +2985,7 @@ const instructions = [
3385
2985
  },
3386
2986
  {
3387
2987
  name: "associated_token_program",
2988
+ optional: true,
3388
2989
  address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
3389
2990
  }
3390
2991
  ],
@@ -3392,64 +2993,187 @@ const instructions = [
3392
2993
  ]
3393
2994
  },
3394
2995
  {
3395
- name: "update_authority",
2996
+ name: "rebalance_with_amounts",
3396
2997
  discriminator: [
3397
- 32,
3398
- 46,
3399
- 64,
3400
- 28,
3401
- 149,
3402
- 75,
3403
- 243,
3404
- 88
2998
+ 190,
2999
+ 33,
3000
+ 144,
3001
+ 182,
3002
+ 86,
3003
+ 4,
3004
+ 141,
3005
+ 73
3405
3006
  ],
3406
3007
  accounts: [
3407
3008
  {
3408
- name: "signer",
3409
- signer: true
3009
+ name: "rebalancer",
3010
+ writable: true,
3011
+ signer: true,
3012
+ relations: [
3013
+ "vault_config"
3014
+ ]
3410
3015
  },
3411
3016
  {
3412
- name: "vault_admin",
3017
+ name: "rebalancer_supply_token_account",
3413
3018
  writable: true
3414
- }
3415
- ],
3416
- args: [
3019
+ },
3417
3020
  {
3418
- name: "new_authority",
3419
- type: "pubkey"
3420
- }
3421
- ]
3422
- },
3423
- {
3424
- name: "update_auths",
3425
- discriminator: [
3426
- 93,
3427
- 96,
3428
- 178,
3429
- 156,
3430
- 57,
3431
- 117,
3432
- 253,
3433
- 209
3434
- ],
3435
- accounts: [
3021
+ name: "rebalancer_borrow_token_account",
3022
+ writable: true
3023
+ },
3436
3024
  {
3437
- name: "signer",
3438
- signer: true
3025
+ name: "vault_config",
3026
+ docs: [
3027
+ "@dev mut because this PDA signs the CPI to liquidity program",
3028
+ "@dev verification inside instruction logic"
3029
+ ],
3030
+ writable: true
3439
3031
  },
3440
3032
  {
3441
- name: "vault_admin",
3033
+ name: "vault_state",
3034
+ docs: [
3035
+ "@dev verification inside instruction logic"
3036
+ ],
3442
3037
  writable: true
3443
- }
3444
- ],
3445
- args: [
3038
+ },
3446
3039
  {
3447
- name: "auth_status",
3448
- type: {
3449
- vec: {
3450
- defined: {
3451
- name: "AddressBool"
3452
- }
3040
+ name: "supply_token",
3041
+ relations: [
3042
+ "vault_config"
3043
+ ]
3044
+ },
3045
+ {
3046
+ name: "borrow_token",
3047
+ relations: [
3048
+ "vault_config"
3049
+ ]
3050
+ },
3051
+ {
3052
+ name: "supply_token_reserves_liquidity",
3053
+ writable: true
3054
+ },
3055
+ {
3056
+ name: "borrow_token_reserves_liquidity",
3057
+ writable: true
3058
+ },
3059
+ {
3060
+ name: "vault_supply_position_on_liquidity",
3061
+ writable: true
3062
+ },
3063
+ {
3064
+ name: "vault_borrow_position_on_liquidity",
3065
+ writable: true
3066
+ },
3067
+ {
3068
+ name: "supply_rate_model"
3069
+ },
3070
+ {
3071
+ name: "borrow_rate_model"
3072
+ },
3073
+ {
3074
+ name: "liquidity"
3075
+ },
3076
+ {
3077
+ name: "liquidity_program"
3078
+ },
3079
+ {
3080
+ name: "vault_supply_token_account",
3081
+ writable: true
3082
+ },
3083
+ {
3084
+ name: "vault_borrow_token_account",
3085
+ writable: true
3086
+ },
3087
+ {
3088
+ name: "system_program",
3089
+ address: "11111111111111111111111111111111"
3090
+ },
3091
+ {
3092
+ name: "supply_token_program"
3093
+ },
3094
+ {
3095
+ name: "borrow_token_program"
3096
+ },
3097
+ {
3098
+ name: "associated_token_program",
3099
+ optional: true,
3100
+ address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
3101
+ }
3102
+ ],
3103
+ args: [
3104
+ {
3105
+ name: "supply_amount",
3106
+ type: {
3107
+ option: "u128"
3108
+ }
3109
+ },
3110
+ {
3111
+ name: "borrow_amount",
3112
+ type: {
3113
+ option: "u128"
3114
+ }
3115
+ }
3116
+ ]
3117
+ },
3118
+ {
3119
+ name: "update_authority",
3120
+ discriminator: [
3121
+ 32,
3122
+ 46,
3123
+ 64,
3124
+ 28,
3125
+ 149,
3126
+ 75,
3127
+ 243,
3128
+ 88
3129
+ ],
3130
+ accounts: [
3131
+ {
3132
+ name: "signer",
3133
+ signer: true
3134
+ },
3135
+ {
3136
+ name: "vault_admin",
3137
+ writable: true
3138
+ }
3139
+ ],
3140
+ args: [
3141
+ {
3142
+ name: "new_authority",
3143
+ type: "pubkey"
3144
+ }
3145
+ ]
3146
+ },
3147
+ {
3148
+ name: "update_auths",
3149
+ discriminator: [
3150
+ 93,
3151
+ 96,
3152
+ 178,
3153
+ 156,
3154
+ 57,
3155
+ 117,
3156
+ 253,
3157
+ 209
3158
+ ],
3159
+ accounts: [
3160
+ {
3161
+ name: "signer",
3162
+ signer: true
3163
+ },
3164
+ {
3165
+ name: "vault_admin",
3166
+ writable: true
3167
+ }
3168
+ ],
3169
+ args: [
3170
+ {
3171
+ name: "auth_status",
3172
+ type: {
3173
+ vec: {
3174
+ defined: {
3175
+ name: "AddressBool"
3176
+ }
3453
3177
  }
3454
3178
  }
3455
3179
  }
@@ -5821,6 +5545,9 @@ const types = [
5821
5545
  },
5822
5546
  {
5823
5547
  name: "ChainlinkDataStreams"
5548
+ },
5549
+ {
5550
+ name: "PstPool"
5824
5551
  }
5825
5552
  ]
5826
5553
  }
@@ -6267,7 +5994,11 @@ const types = [
6267
5994
  },
6268
5995
  {
6269
5996
  name: "withdrawal_limit",
6270
- type: "u128"
5997
+ type: "u64"
5998
+ },
5999
+ {
6000
+ name: "decay_amount",
6001
+ type: "u64"
6271
6002
  },
6272
6003
  {
6273
6004
  name: "last_update",
@@ -6279,7 +6010,11 @@ const types = [
6279
6010
  },
6280
6011
  {
6281
6012
  name: "expand_duration",
6282
- type: "u64"
6013
+ type: "u32"
6014
+ },
6015
+ {
6016
+ name: "decay_duration",
6017
+ type: "u32"
6283
6018
  },
6284
6019
  {
6285
6020
  name: "base_withdrawal_limit",
@@ -6539,6 +6274,45 @@ const X30 = new BN(1073741823);
6539
6274
  const MIN_I128 = new BN("170141183460469231731687303715884105728").neg();
6540
6275
  const MAX_REPAY_AMOUNT = MIN_I128;
6541
6276
  const MAX_WITHDRAW_AMOUNT = MIN_I128;
6277
+ const MAX_TOKEN_DECIMALS = 9;
6278
+ const LOWER_DECIMALS_OPERATE = 4;
6279
+ const MIN_DEBT = new BN(1e3);
6280
+ const MIN_DEBT_LOWER_DECIMALS = new BN(10);
6281
+ const LIQUIDATED_POSITION_DEBT_MULTIPLIER = new BN(2);
6282
+ function getMinimumDebt(decimals) {
6283
+ if (decimals > MAX_TOKEN_DECIMALS) {
6284
+ throw new Error(`Unsupported token decimals: ${decimals}`);
6285
+ }
6286
+ const base = decimals >= LOWER_DECIMALS_OPERATE ? MIN_DEBT : MIN_DEBT_LOWER_DECIMALS;
6287
+ return base.mul(new BN(10).pow(new BN(MAX_TOKEN_DECIMALS - decimals)));
6288
+ }
6289
+ function reconcileLiquidatedDust({
6290
+ finalTick,
6291
+ finalColRaw,
6292
+ finalDebtRaw,
6293
+ dustDebtRaw,
6294
+ borrowMintDecimals
6295
+ }) {
6296
+ const absorbThreshold = getMinimumDebt(borrowMintDecimals).mul(
6297
+ LIQUIDATED_POSITION_DEBT_MULTIPLIER
6298
+ );
6299
+ if (finalDebtRaw.lt(dustDebtRaw) || finalDebtRaw.lt(absorbThreshold)) {
6300
+ return {
6301
+ tick: MIN_TICK,
6302
+ colRaw: new BN(0),
6303
+ debtRaw: new BN(0),
6304
+ dustDebtRaw: new BN(0),
6305
+ isWiped: true
6306
+ };
6307
+ }
6308
+ return {
6309
+ tick: finalTick,
6310
+ colRaw: finalColRaw,
6311
+ debtRaw: finalDebtRaw,
6312
+ dustDebtRaw,
6313
+ isWiped: false
6314
+ };
6315
+ }
6542
6316
  const getAccountOwner = async (account, connection) => {
6543
6317
  const info = await connection.getAccountInfo(account);
6544
6318
  if (!info)
@@ -6566,7 +6340,8 @@ const getCurrentPositionState = async ({
6566
6340
  vaultId,
6567
6341
  position,
6568
6342
  program,
6569
- market
6343
+ market,
6344
+ borrowMintDecimals
6570
6345
  }) => {
6571
6346
  let positionTick = position.tick;
6572
6347
  if (positionTick === INIT_TICK) {
@@ -6651,17 +6426,27 @@ const getCurrentPositionState = async ({
6651
6426
  initialConnectionFactor: connectionFactor,
6652
6427
  initialDebtRaw: debtRaw
6653
6428
  });
6654
- const netDebtRaw2 = finalDebtRaw.gt(dustDebtRaw) ? finalDebtRaw.sub(dustDebtRaw) : new BN(0);
6655
- return {
6656
- tick: finalTick,
6657
- tickId: position.tickId,
6658
- colRaw: finalColRaw,
6659
- debtRaw: finalDebtRaw,
6429
+ const borrowDecimals = borrowMintDecimals ?? (await program.account.vaultMetadata.fetch(
6430
+ getVaultMetadata(vaultId, market)
6431
+ )).borrowMintDecimals;
6432
+ const reconciled = reconcileLiquidatedDust({
6433
+ finalTick,
6434
+ finalColRaw,
6435
+ finalDebtRaw,
6660
6436
  dustDebtRaw,
6661
- finalAmount: netDebtRaw2.gt(new BN(0)) ? finalColRaw : new BN(0),
6662
- isSupplyOnlyPosition: finalTick === MIN_TICK,
6437
+ borrowMintDecimals: borrowDecimals
6438
+ });
6439
+ const netDebtRaw2 = reconciled.debtRaw.gt(reconciled.dustDebtRaw) ? reconciled.debtRaw.sub(reconciled.dustDebtRaw) : new BN(0);
6440
+ return {
6441
+ tick: reconciled.tick,
6442
+ tickId: reconciled.isWiped ? 0 : position.tickId,
6443
+ colRaw: reconciled.colRaw,
6444
+ debtRaw: reconciled.debtRaw,
6445
+ dustDebtRaw: reconciled.dustDebtRaw,
6446
+ finalAmount: netDebtRaw2.gt(new BN(0)) ? reconciled.colRaw : new BN(0),
6447
+ isSupplyOnlyPosition: reconciled.tick === MIN_TICK,
6663
6448
  userLiquidationStatus,
6664
- postLiquidationBranchId
6449
+ postLiquidationBranchId: reconciled.isWiped ? 0 : postLiquidationBranchId
6665
6450
  };
6666
6451
  }
6667
6452
  }
@@ -7055,6 +6840,26 @@ async function loadRelevantBranchesForLiquidate(vaultId, vaultState, program, ma
7055
6840
  if (!doesBranchExist(0)) branches.push({ branchId: 0 });
7056
6841
  return branches;
7057
6842
  }
6843
+ async function getOracleSources({
6844
+ connection,
6845
+ signer,
6846
+ oracle: oracle$1
6847
+ }) {
6848
+ const program = new Program(
6849
+ oracle,
6850
+ new AnchorProvider(connection, {
6851
+ signTransaction() {
6852
+ throw new Error("Not implemented");
6853
+ },
6854
+ signAllTransactions() {
6855
+ throw new Error("Not implemented");
6856
+ },
6857
+ publicKey: signer ?? new PublicKey("HEyJLdMfZhhQ7FHCtjD5DWDFNFQhaeAVAsHeWqoY6dSD")
6858
+ })
6859
+ );
6860
+ const oracleData = await program.account.oracle.fetch(oracle$1);
6861
+ return oracleData.sources;
6862
+ }
7058
6863
  async function readOraclePrice({
7059
6864
  connection,
7060
6865
  signer,
@@ -7095,841 +6900,4 @@ const getLiquidityProgramId = (market) => {
7095
6900
  return market === "ethena" ? new PublicKey("jup6QF1sNDGpkkcu6F4qaFHcRBmnSS1VgyB4uFbBvNS") : new PublicKey("jupeiUmn818Jg1ekPURTpr4mFo29p46vygyykFJ3wZC");
7096
6901
  };
7097
6902
 
7098
- const MPL_TOKEN_METADATA_PROGRAM_ID = new PublicKey(
7099
- "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"
7100
- );
7101
- async function getOtherInstructionsOperate(vaultId, vaultState, currentPosition, finalPosition, currentTick, currentTickId, program, signer, market) {
7102
- const otherIxs = [];
7103
- const tickToRead = [currentTick];
7104
- let finalTickData;
7105
- tickToRead.push(currentPosition.tick);
7106
- tickToRead.push(finalPosition.tick);
7107
- if (tickToRead.length > 0) {
7108
- const tickData = await program.account.tick.fetchMultiple(
7109
- tickToRead.map((tick) => getTick(vaultId, tick, market))
7110
- );
7111
- tickData[0];
7112
- finalTickData = tickData[2];
7113
- for (const [i, tickDatum] of tickData.entries()) {
7114
- if (!tickDatum) {
7115
- const ix = await program.methods.initTick(vaultId, tickToRead[i]).accounts(getInitTickContext(vaultId, tickToRead[i], signer, market)).instruction();
7116
- otherIxs.push(ix);
7117
- }
7118
- }
7119
- }
7120
- let newBranchId;
7121
- if (vaultState.branchLiquidated) {
7122
- newBranchId = vaultState.totalBranchId + 1;
7123
- let newBranchData = null;
7124
- try {
7125
- newBranchData = await program.account.branch.fetch(
7126
- getBranch(vaultId, newBranchId, market)
7127
- );
7128
- } catch {
7129
- }
7130
- if (!newBranchData) {
7131
- const ix = await program.methods.initBranch(vaultId, newBranchId).accounts(getInitBranchContext(vaultId, newBranchId, signer, market)).instruction();
7132
- otherIxs.push(ix);
7133
- }
7134
- } else {
7135
- newBranchId = vaultState.currentBranchId;
7136
- }
7137
- const newBranchPda = getBranch(vaultId, newBranchId, market);
7138
- const currentTickIdDataPda = getTickIdLiquidation(
7139
- vaultId,
7140
- currentTick,
7141
- // Position tick
7142
- currentTickId,
7143
- // Position tick ID
7144
- market
7145
- );
7146
- const tickIdsToRead = [
7147
- {
7148
- tick: currentTick,
7149
- totalIds: currentTickId
7150
- }
7151
- ];
7152
- const finalTickIdDataPda = getTickIdLiquidation(
7153
- vaultId,
7154
- finalPosition.tick,
7155
- finalTickData ? finalTickData.totalIds : 0,
7156
- market
7157
- );
7158
- if (finalPosition.tick !== currentTick)
7159
- if (finalTickData) {
7160
- tickIdsToRead.push({
7161
- tick: finalPosition.tick,
7162
- totalIds: finalTickData.totalIds
7163
- });
7164
- } else {
7165
- const context = await getInitTickIdLiquidationContext(
7166
- vaultId,
7167
- finalPosition.tick,
7168
- signer,
7169
- program,
7170
- market
7171
- );
7172
- const ix = await program.methods.initTickIdLiquidation(vaultId, finalPosition.tick, 0).accounts(context).instruction();
7173
- otherIxs.push(ix);
7174
- }
7175
- const tickIdData = await program.account.tickIdLiquidation.fetchMultiple(
7176
- tickIdsToRead.map(
7177
- ({ tick, totalIds }) => getTickIdLiquidation(vaultId, tick, totalIds, market)
7178
- )
7179
- );
7180
- if (tickIdData.length > 0) {
7181
- for (const [i, tickIdDatum] of tickIdData.entries()) {
7182
- if (!tickIdDatum) {
7183
- const ix = await program.methods.initTickIdLiquidation(
7184
- vaultId,
7185
- tickIdsToRead[i].tick,
7186
- tickIdsToRead[i].totalIds
7187
- ).accounts(
7188
- await getInitTickIdLiquidationContext(
7189
- vaultId,
7190
- tickIdsToRead[i].tick,
7191
- signer,
7192
- program,
7193
- market
7194
- )
7195
- ).instruction();
7196
- otherIxs.push(ix);
7197
- }
7198
- }
7199
- }
7200
- return {
7201
- otherIxs,
7202
- newBranchPda,
7203
- currentTickIdDataPda,
7204
- finalTickIdDataPda
7205
- };
7206
- }
7207
- const tickHelper = (tickValue) => {
7208
- return tickValue === 0 ? INIT_TICK : tickValue;
7209
- };
7210
- async function getRemainingAccountsOperate(vaultId, vaultState, vaultConfig, finalPositionTick, existingPositionTick, liquidationStatus, postLiquidationBranchId, program, market) {
7211
- const remainingAccounts = [];
7212
- const oracleProgram = new Program(oracle, program.provider);
7213
- const [oracleData, branches, tickHasDebt] = await Promise.all([
7214
- oracleProgram.account.oracle.fetch(new PublicKey(vaultConfig.oracle)),
7215
- // Add branch accounts (next 10 remaining accounts)
7216
- loadRelevantBranches(
7217
- vaultId,
7218
- vaultState,
7219
- liquidationStatus,
7220
- postLiquidationBranchId,
7221
- program,
7222
- market
7223
- ),
7224
- loadRelevantTicksHasDebtArrays(
7225
- vaultId,
7226
- tickHelper(vaultState.topmostTick),
7227
- existingPositionTick,
7228
- finalPositionTick,
7229
- program,
7230
- market
7231
- )
7232
- ]);
7233
- const sourceLength = oracleData.sources.length;
7234
- for (const source of oracleData.sources)
7235
- remainingAccounts.push({
7236
- pubkey: new PublicKey(source.source),
7237
- isWritable: false,
7238
- isSigner: false
7239
- });
7240
- const branchLength = branches.length;
7241
- for (const branch of branches) {
7242
- remainingAccounts.push({
7243
- pubkey: getBranch(vaultId, branch, market),
7244
- isWritable: true,
7245
- isSigner: false
7246
- });
7247
- }
7248
- const tickHasDebtLength = tickHasDebt.length;
7249
- for (const tickHasDebtArray of tickHasDebt)
7250
- remainingAccounts.push({
7251
- pubkey: tickHasDebtArray,
7252
- isWritable: true,
7253
- isSigner: false
7254
- });
7255
- const remainingAccountsIndices = [
7256
- sourceLength,
7257
- branchLength,
7258
- tickHasDebtLength
7259
- ];
7260
- return {
7261
- remainingAccounts,
7262
- remainingAccountsIndices
7263
- };
7264
- }
7265
- async function getOperateContext({
7266
- vaultId,
7267
- positionId,
7268
- program,
7269
- connection,
7270
- signer,
7271
- positionOwner = signer,
7272
- colAmount: newCol,
7273
- debtAmount: newDebt,
7274
- recipient,
7275
- market
7276
- }) {
7277
- program = program ?? getVaultsProgram({ connection, signer, market });
7278
- const [vaultState, vaultConfig, vaultMetadata] = await Promise.all([
7279
- program.account.vaultState.fetch(getVaultState(vaultId, market)),
7280
- program.account.vaultConfig.fetch(
7281
- getVaultConfig(vaultId, market)
7282
- ),
7283
- program.account.vaultMetadata.fetch(
7284
- getVaultMetadata(vaultId, market)
7285
- )
7286
- ]);
7287
- const [supplyTokenProgram, borrowTokenProgram] = await Promise.all([
7288
- getAccountOwner(vaultConfig.supplyToken, connection),
7289
- getAccountOwner(vaultConfig.borrowToken, connection)
7290
- ]);
7291
- const vaultSupplyDecimals = vaultMetadata.supplyMintDecimals;
7292
- const vaultBorrowDecimals = vaultMetadata.borrowMintDecimals;
7293
- if (newCol.gt(MIN_I128)) {
7294
- const decimalsDelta = vaultSupplyDecimals < 9 ? 9 - vaultSupplyDecimals : 0;
7295
- newCol = newCol.mul(new BN(10).pow(new BN(decimalsDelta)));
7296
- }
7297
- if (newDebt.gt(MIN_I128)) {
7298
- const decimalsDelta = vaultBorrowDecimals < 9 ? 9 - vaultBorrowDecimals : 0;
7299
- newDebt = newDebt.mul(new BN(10).pow(new BN(decimalsDelta)));
7300
- }
7301
- const positionData = positionId === 0 ? {
7302
- nftId: vaultState.nextPositionId,
7303
- positionMint: new PublicKey(0),
7304
- isSupplyOnlyPosition: 1,
7305
- tick: -2147483648,
7306
- tickId: 0,
7307
- lastUpdateTimestamp: new BN(0),
7308
- supplyAmount: new BN(0),
7309
- dustDebtAmount: new BN(0)} : await program.account.position.fetch(
7310
- getPosition(vaultId, positionId, market)
7311
- );
7312
- let existingPositionTick = positionData.tick;
7313
- let existingPositionTickId = positionData.tickId;
7314
- const currentPosition = await getCurrentPositionState({
7315
- vaultId,
7316
- position: positionData,
7317
- program,
7318
- market
7319
- });
7320
- if (existingPositionTick === -2147483648) {
7321
- existingPositionTick = currentPosition.tick;
7322
- existingPositionTickId = 0;
7323
- }
7324
- const currentPositionTickPda = getTick(
7325
- vaultId,
7326
- existingPositionTick,
7327
- market
7328
- );
7329
- const finalPosition = await getFinalPosition({
7330
- vaultId,
7331
- currentPosition,
7332
- newColAmount: newCol,
7333
- newDebtAmount: newDebt,
7334
- program,
7335
- connection,
7336
- signer,
7337
- market
7338
- });
7339
- const { otherIxs, newBranchPda, currentTickIdDataPda, finalTickIdDataPda } = await getOtherInstructionsOperate(
7340
- vaultId,
7341
- vaultState,
7342
- currentPosition,
7343
- finalPosition,
7344
- existingPositionTick,
7345
- existingPositionTickId,
7346
- program,
7347
- signer,
7348
- market
7349
- );
7350
- const { remainingAccounts, remainingAccountsIndices } = await getRemainingAccountsOperate(
7351
- vaultId,
7352
- vaultState,
7353
- vaultConfig,
7354
- finalPosition.tick,
7355
- existingPositionTick,
7356
- currentPosition.userLiquidationStatus,
7357
- currentPosition.postLiquidationBranchId,
7358
- program,
7359
- market
7360
- );
7361
- const accounts = {
7362
- signer,
7363
- signerSupplyTokenAccount: getAssociatedTokenAddressSync(
7364
- vaultConfig.supplyToken,
7365
- signer,
7366
- true,
7367
- supplyTokenProgram
7368
- ),
7369
- signerBorrowTokenAccount: getAssociatedTokenAddressSync(
7370
- vaultConfig.borrowToken,
7371
- signer,
7372
- true,
7373
- borrowTokenProgram
7374
- ),
7375
- recipient: recipient ?? null,
7376
- recipientSupplyTokenAccount: recipient ? getAssociatedTokenAddressSync(
7377
- vaultConfig.supplyToken,
7378
- recipient,
7379
- true,
7380
- supplyTokenProgram
7381
- ) : null,
7382
- recipientBorrowTokenAccount: recipient ? getAssociatedTokenAddressSync(
7383
- vaultConfig.borrowToken,
7384
- recipient,
7385
- true,
7386
- borrowTokenProgram
7387
- ) : null,
7388
- vaultConfig: getVaultConfig(vaultId, market),
7389
- vaultState: getVaultState(vaultId, market),
7390
- supplyToken: vaultConfig.supplyToken,
7391
- borrowToken: vaultConfig.borrowToken,
7392
- oracle: new PublicKey(vaultConfig.oracle),
7393
- position: getPosition(vaultId, positionData.nftId, market),
7394
- positionTokenAccount: getPositionTokenAccount(
7395
- vaultId,
7396
- positionData.nftId,
7397
- positionOwner,
7398
- market
7399
- ),
7400
- currentPositionTick: currentPositionTickPda,
7401
- finalPositionTick: getTick(vaultId, finalPosition.tick, market),
7402
- currentPositionTickId: currentTickIdDataPda,
7403
- finalPositionTickId: finalTickIdDataPda,
7404
- newBranch: newBranchPda,
7405
- supplyTokenReservesLiquidity: getLiquidityReserve(
7406
- vaultConfig.supplyToken,
7407
- market
7408
- ),
7409
- borrowTokenReservesLiquidity: getLiquidityReserve(
7410
- vaultConfig.borrowToken,
7411
- market
7412
- ),
7413
- vaultSupplyPositionOnLiquidity: getUserSupplyPosition(
7414
- vaultConfig.supplyToken,
7415
- getVaultConfig(vaultId, market),
7416
- market
7417
- ),
7418
- vaultBorrowPositionOnLiquidity: getUserBorrowPosition(
7419
- vaultConfig.borrowToken,
7420
- getVaultConfig(vaultId, market),
7421
- market
7422
- ),
7423
- supplyRateModel: getRateModel(vaultConfig.supplyToken, market),
7424
- borrowRateModel: getRateModel(vaultConfig.borrowToken, market),
7425
- supplyTokenClaimAccount: null,
7426
- borrowTokenClaimAccount: null,
7427
- liquidity: getLiquidity(market),
7428
- liquidityProgram: getLiquidityProgramId(market),
7429
- vaultSupplyTokenAccount: getAssociatedTokenAddressSync(
7430
- vaultConfig.supplyToken,
7431
- getLiquidity(market),
7432
- true,
7433
- supplyTokenProgram
7434
- ),
7435
- vaultBorrowTokenAccount: getAssociatedTokenAddressSync(
7436
- vaultConfig.borrowToken,
7437
- getLiquidity(market),
7438
- true,
7439
- borrowTokenProgram
7440
- ),
7441
- oracleProgram: new PublicKey(vaultConfig.oracleProgram),
7442
- supplyTokenProgram,
7443
- borrowTokenProgram,
7444
- associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
7445
- systemProgram: SystemProgram.programId
7446
- };
7447
- return {
7448
- nftId: positionData.nftId,
7449
- accounts,
7450
- remainingAccounts,
7451
- initPositionIx: positionId === 0 ? await program.methods.initPosition(vaultId, positionData.nftId).accounts(
7452
- getInitPositionContext(
7453
- vaultId,
7454
- positionData.nftId,
7455
- signer,
7456
- market
7457
- )
7458
- ).instruction() : null,
7459
- otherIxs,
7460
- remainingAccountsIndices,
7461
- lookupTable: vaultMetadata.lookupTable
7462
- };
7463
- }
7464
- async function getInitPositionIx({
7465
- vaultId,
7466
- connection,
7467
- signer,
7468
- market = "main"
7469
- }) {
7470
- const program = getVaultsProgram({ connection, signer, market });
7471
- const vaultState = await program.account.vaultState.fetch(
7472
- getVaultState(vaultId, market)
7473
- );
7474
- return {
7475
- ix: await program.methods.initPosition(vaultId, vaultState.nextPositionId).accounts(
7476
- getInitPositionContext(
7477
- vaultId,
7478
- vaultState.nextPositionId,
7479
- signer,
7480
- market
7481
- )
7482
- ).instruction(),
7483
- nftId: vaultState.nextPositionId
7484
- };
7485
- }
7486
- function getInitPositionContext(vaultId, positionId, signer, market) {
7487
- return {
7488
- signer,
7489
- vaultAdmin: getVaultAdmin(market),
7490
- vaultState: getVaultState(vaultId, market),
7491
- position: getPosition(vaultId, positionId, market),
7492
- positionMint: getPositionMint(vaultId, positionId, market),
7493
- positionTokenAccount: getPositionTokenAccount(
7494
- vaultId,
7495
- positionId,
7496
- signer,
7497
- market
7498
- ),
7499
- tokenProgram: TOKEN_PROGRAM_ID,
7500
- metadataAccount: getPositionMetadata(vaultId, positionId, market),
7501
- associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
7502
- systemProgram: SystemProgram.programId,
7503
- sysvarInstruction: SYSVAR_INSTRUCTIONS_PUBKEY,
7504
- metadataProgram: MPL_TOKEN_METADATA_PROGRAM_ID,
7505
- rent: SYSVAR_RENT_PUBKEY
7506
- };
7507
- }
7508
- const getOperateIx = async ({
7509
- vaultId,
7510
- positionId,
7511
- colAmount,
7512
- debtAmount,
7513
- connection,
7514
- signer,
7515
- recipient,
7516
- positionOwner,
7517
- market = "main"
7518
- }) => {
7519
- const program = getVaultsProgram({ connection, signer, market });
7520
- const {
7521
- accounts,
7522
- remainingAccounts,
7523
- remainingAccountsIndices,
7524
- initPositionIx,
7525
- otherIxs,
7526
- lookupTable,
7527
- nftId
7528
- } = await getOperateContext({
7529
- vaultId,
7530
- positionId,
7531
- colAmount,
7532
- debtAmount,
7533
- signer,
7534
- positionOwner,
7535
- connection,
7536
- recipient,
7537
- program,
7538
- market
7539
- });
7540
- if (accounts.borrowToken.toString() !== NATIVE_MINT.toString() && debtAmount.lt(new BN(0))) {
7541
- try {
7542
- const userDebtTokenBalance = await connection.getTokenAccountBalance(
7543
- accounts.signerBorrowTokenAccount
7544
- );
7545
- if (userDebtTokenBalance.value.amount === debtAmount.abs().toString()) {
7546
- debtAmount = debtAmount.add(new BN(1));
7547
- }
7548
- } catch {
7549
- }
7550
- }
7551
- const [operateIx, addressLookupTable] = await Promise.all([
7552
- program.methods.operate(
7553
- colAmount,
7554
- debtAmount,
7555
- { direct: {} },
7556
- Buffer.from(remainingAccountsIndices)
7557
- ).accounts(accounts).remainingAccounts(remainingAccounts).instruction(),
7558
- connection.getAddressLookupTable(lookupTable)
7559
- ]);
7560
- return {
7561
- nftId,
7562
- accounts,
7563
- remainingAccounts,
7564
- remainingAccountsIndices,
7565
- addressLookupTableAddresses: lookupTable ? [lookupTable] : [],
7566
- addressLookupTableAccounts: addressLookupTable.value ? [addressLookupTable.value] : [],
7567
- ixs: initPositionIx ? [initPositionIx, ...otherIxs, operateIx] : [...otherIxs, operateIx]
7568
- };
7569
- };
7570
- function getInitBranchContext(vaultId, branchId, signer, market) {
7571
- return {
7572
- signer,
7573
- vaultConfig: getVaultConfig(vaultId, market),
7574
- branch: getBranch(vaultId, branchId, market),
7575
- systemProgram: SystemProgram.programId
7576
- };
7577
- }
7578
- function getInitTickContext(vaultId, tick, signer, market) {
7579
- return {
7580
- signer,
7581
- vaultConfig: getVaultConfig(vaultId, market),
7582
- tickData: getTick(vaultId, tick, market),
7583
- systemProgram: SystemProgram.programId
7584
- };
7585
- }
7586
- async function getInitTickIdLiquidationContext(vaultId, tick, signer, program, market) {
7587
- const tickData = await program.account.tick.fetch(getTick(vaultId, tick, market)).catch(() => null);
7588
- if (!tickData) {
7589
- return {
7590
- signer,
7591
- vaultConfig: getVaultConfig(vaultId, market),
7592
- tickIdLiquidation: getTickIdLiquidation(
7593
- vaultId,
7594
- tick,
7595
- 0,
7596
- market
7597
- ),
7598
- tickData: getTick(vaultId, tick, market),
7599
- systemProgram: SystemProgram.programId
7600
- };
7601
- }
7602
- return {
7603
- signer,
7604
- vaultConfig: getVaultConfig(vaultId, market),
7605
- tickIdLiquidation: getTickIdLiquidation(
7606
- vaultId,
7607
- tick,
7608
- tickData.totalIds,
7609
- market
7610
- ),
7611
- tickData: getTick(vaultId, tick, market),
7612
- systemProgram: SystemProgram.programId
7613
- };
7614
- }
7615
- async function getLiquidateContext({
7616
- vaultId,
7617
- to,
7618
- program,
7619
- connection,
7620
- signer,
7621
- market
7622
- }) {
7623
- program = program ?? getVaultsProgram({ connection, signer, market });
7624
- const [vaultState, vaultConfig, vaultMetadata] = await Promise.all([
7625
- program.account.vaultState.fetch(getVaultState(vaultId, market)),
7626
- program.account.vaultConfig.fetch(
7627
- getVaultConfig(vaultId, market)
7628
- ),
7629
- program.account.vaultMetadata.fetch(
7630
- getVaultMetadata(vaultId, market)
7631
- )
7632
- ]);
7633
- const [supplyTokenProgram, borrowTokenProgram] = await Promise.all([
7634
- getAccountOwner(vaultConfig.supplyToken, connection),
7635
- getAccountOwner(vaultConfig.borrowToken, connection)
7636
- ]);
7637
- const { arrayIndex } = getTickIndices(vaultState.topmostTick);
7638
- let { otherIxs, newBranchPda } = await getOtherInstructionsLiquidate(
7639
- vaultId,
7640
- vaultState,
7641
- program,
7642
- signer,
7643
- market
7644
- );
7645
- const {
7646
- remainingAccounts,
7647
- remainingAccountsIndices,
7648
- otherIxs: finalOtherIxs
7649
- } = await getRemainingAccountsLiquidate(
7650
- vaultId,
7651
- vaultState,
7652
- vaultConfig,
7653
- otherIxs,
7654
- program,
7655
- connection,
7656
- signer,
7657
- market
7658
- );
7659
- return {
7660
- accounts: {
7661
- signer,
7662
- signerTokenAccount: getAssociatedTokenAddressSync(
7663
- vaultConfig.borrowToken,
7664
- signer,
7665
- false,
7666
- borrowTokenProgram
7667
- ),
7668
- to,
7669
- toTokenAccount: getAssociatedTokenAddressSync(
7670
- vaultConfig.supplyToken,
7671
- to,
7672
- false,
7673
- supplyTokenProgram
7674
- ),
7675
- vaultAdmin: getVaultAdmin(market),
7676
- vaultConfig: getVaultConfig(vaultId, market),
7677
- vaultState: getVaultState(vaultId, market),
7678
- supplyToken: vaultConfig.supplyToken,
7679
- borrowToken: vaultConfig.borrowToken,
7680
- oracle: new PublicKey(vaultConfig.oracle),
7681
- tickHasDebt: getTickHasDebt(vaultId, arrayIndex, market),
7682
- newBranch: newBranchPda,
7683
- supplyTokenReservesLiquidity: getLiquidityReserve(
7684
- vaultConfig.supplyToken,
7685
- market
7686
- ),
7687
- borrowTokenReservesLiquidity: getLiquidityReserve(
7688
- vaultConfig.borrowToken,
7689
- market
7690
- ),
7691
- vaultSupplyPositionOnLiquidity: getUserSupplyPosition(
7692
- vaultConfig.supplyToken,
7693
- getVaultConfig(vaultId, market),
7694
- market
7695
- ),
7696
- vaultBorrowPositionOnLiquidity: getUserBorrowPosition(
7697
- vaultConfig.borrowToken,
7698
- getVaultConfig(vaultId, market),
7699
- market
7700
- ),
7701
- supplyRateModel: getRateModel(vaultConfig.supplyToken, market),
7702
- borrowRateModel: getRateModel(vaultConfig.borrowToken, market),
7703
- supplyTokenClaimAccount: getClaimAccount(
7704
- vaultConfig.supplyToken,
7705
- getVaultConfig(vaultId, market),
7706
- market
7707
- ),
7708
- borrowTokenClaimAccount: getClaimAccount(
7709
- vaultConfig.borrowToken,
7710
- getVaultConfig(vaultId, market),
7711
- market
7712
- ),
7713
- liquidity: getLiquidity(market),
7714
- liquidityProgram: getLiquidityProgramId(market),
7715
- vaultSupplyTokenAccount: getAssociatedTokenAddressSync(
7716
- vaultConfig.supplyToken,
7717
- getLiquidity(market),
7718
- true,
7719
- supplyTokenProgram
7720
- ),
7721
- vaultBorrowTokenAccount: getAssociatedTokenAddressSync(
7722
- vaultConfig.borrowToken,
7723
- getLiquidity(market),
7724
- true,
7725
- borrowTokenProgram
7726
- ),
7727
- oracleProgram: new PublicKey(vaultConfig.oracleProgram),
7728
- supplyTokenProgram,
7729
- borrowTokenProgram,
7730
- systemProgram: SystemProgram.programId,
7731
- associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID
7732
- },
7733
- remainingAccounts,
7734
- otherIxs: finalOtherIxs,
7735
- remainingAccountsIndices,
7736
- lookupTable: vaultMetadata.lookupTable
7737
- };
7738
- }
7739
- const getLiquidateIx = async ({
7740
- vaultId,
7741
- debtAmount,
7742
- colPerUnitDebt = new BN(0),
7743
- absorb = false,
7744
- signer,
7745
- to = signer,
7746
- connection,
7747
- market
7748
- }) => {
7749
- const program = getVaultsProgram({ connection, signer, market });
7750
- const {
7751
- accounts,
7752
- remainingAccounts,
7753
- remainingAccountsIndices,
7754
- otherIxs,
7755
- lookupTable
7756
- } = await getLiquidateContext({
7757
- vaultId,
7758
- to,
7759
- program,
7760
- signer,
7761
- connection,
7762
- market
7763
- });
7764
- const ixs = [];
7765
- if (otherIxs.length > 0) {
7766
- ixs.push(...otherIxs);
7767
- }
7768
- const [ix, addressLookupTable] = await Promise.all([
7769
- program.methods.liquidate(
7770
- debtAmount,
7771
- colPerUnitDebt,
7772
- absorb,
7773
- { direct: {} },
7774
- Buffer.from(remainingAccountsIndices)
7775
- ).accounts(accounts).remainingAccounts(remainingAccounts).instruction(),
7776
- connection.getAddressLookupTable(lookupTable)
7777
- ]);
7778
- ixs.push(ix);
7779
- return {
7780
- accounts,
7781
- remainingAccounts,
7782
- remainingAccountsIndices,
7783
- ixs,
7784
- addressLookupTableAddresses: lookupTable ? [lookupTable] : [],
7785
- addressLookupTableAccounts: addressLookupTable.value ? [addressLookupTable.value] : []
7786
- };
7787
- };
7788
- async function getOtherInstructionsLiquidate(vaultId, vaultState, program, signer, market) {
7789
- const otherIxs = [];
7790
- let newBranchId = vaultState.branchLiquidated === 1 ? vaultState.totalBranchId + 1 : vaultState.currentBranchId;
7791
- let newBranchPda = getBranch(
7792
- vaultId,
7793
- newBranchId,
7794
- market
7795
- );
7796
- const [newBranchData, tickData] = await Promise.all([
7797
- program.account.branch.fetch(newBranchPda).catch(() => null),
7798
- // might be possible that liquidation ends on a tick that is not initialized
7799
- program.account.tick.fetch(getTick(vaultId, vaultState.topmostTick, market)).catch(() => null)
7800
- ]);
7801
- if (!newBranchData) {
7802
- const ix = await program.methods.initBranch(vaultId, newBranchId).accounts(getInitBranchContext(vaultId, newBranchId, signer, market)).instruction();
7803
- otherIxs.push(ix);
7804
- }
7805
- if (!tickData) {
7806
- const ix = await program.methods.initTick(vaultId, vaultState.topmostTick).accounts(
7807
- getInitTickContext(vaultId, vaultState.topmostTick, signer, market)
7808
- ).instruction();
7809
- otherIxs.push(ix);
7810
- }
7811
- return {
7812
- otherIxs,
7813
- newBranchPda
7814
- };
7815
- }
7816
- async function loadRelevantTicksForLiquidate(vaultId, vaultState, liquidationTick, program, market) {
7817
- const ticks = [];
7818
- let topTick = vaultState.topmostTick;
7819
- if (topTick > liquidationTick)
7820
- try {
7821
- const topTickData = await program.account.tick.fetch(
7822
- getTick(vaultId, topTick, market)
7823
- );
7824
- if (topTickData) ticks.push({ ...topTickData, tick: topTick });
7825
- } catch {
7826
- }
7827
- let nextTick = MIN_TICK$1;
7828
- try {
7829
- nextTick = await findNextTickWithDebt(vaultId, topTick, program, market);
7830
- } catch {
7831
- }
7832
- const doesTickExist = (tick) => ticks.some((t) => t.tick === tick);
7833
- while (nextTick > liquidationTick && !doesTickExist(nextTick)) {
7834
- try {
7835
- const nextTickData = await program.account.tick.fetch(
7836
- getTick(vaultId, nextTick, market)
7837
- );
7838
- if (nextTickData) ticks.push({ ...nextTickData, tick: nextTick });
7839
- else throw new Error("Tick not found to load");
7840
- nextTick = await findNextTickWithDebt(vaultId, nextTick, program, market);
7841
- } catch {
7842
- }
7843
- }
7844
- return { ticks, nextTick };
7845
- }
7846
- async function getRemainingAccountsLiquidate(vaultId, vaultState, vaultConfig, otherIxs, program, connection, signer, market) {
7847
- const remainingAccounts = [];
7848
- const { oraclePriceLiquidate, oracleSources } = await readOraclePrice({
7849
- oracle: vaultConfig.oracle,
7850
- connection
7851
- // signer,
7852
- });
7853
- const liquidationRatio = new BN(oraclePriceLiquidate).mul(new BN(281474976710656)).div(new BN(10).pow(new BN(15)));
7854
- const liquidationThresholdRatio = liquidationRatio.mul(new BN(vaultConfig.liquidationThreshold)).div(new BN(10).pow(new BN(3)));
7855
- const liquidationTick = getTickAtRatio(liquidationThresholdRatio);
7856
- for (const source of oracleSources) {
7857
- remainingAccounts.push({
7858
- pubkey: source.source,
7859
- isWritable: false,
7860
- isSigner: false
7861
- });
7862
- }
7863
- const [branches, { ticks: tickAccounts, nextTick }] = await Promise.all([
7864
- loadRelevantBranchesForLiquidate(vaultId, vaultState, program, market),
7865
- loadRelevantTicksForLiquidate(
7866
- vaultId,
7867
- vaultState,
7868
- liquidationTick,
7869
- program,
7870
- market
7871
- )
7872
- ]);
7873
- const tickHasDebt = await loadRelevantTicksHasDebtArraysLiquidate(
7874
- vaultId,
7875
- vaultState.topmostTick,
7876
- nextTick,
7877
- program,
7878
- market
7879
- );
7880
- for (const branch of branches) {
7881
- remainingAccounts.push({
7882
- pubkey: getBranch(vaultId, branch.branchId, market),
7883
- isWritable: true,
7884
- isSigner: false
7885
- });
7886
- }
7887
- const tickToInit = [];
7888
- const existingTicks = await Promise.all(
7889
- tickAccounts.map(
7890
- (tickData) => program.account.tick.fetch(getTick(vaultId, tickData.tick, market)).catch(() => null)
7891
- )
7892
- );
7893
- const initInstructions = await Promise.all(
7894
- tickAccounts.map(async (tickData, index) => {
7895
- const existingTick = existingTicks[index];
7896
- if (!existingTick && !tickToInit.includes(tickData.tick)) {
7897
- tickToInit.push(tickData.tick);
7898
- return program.methods.initTick(vaultId, tickData.tick).accounts(getInitTickContext(vaultId, tickData.tick, signer, market)).instruction();
7899
- }
7900
- return null;
7901
- })
7902
- );
7903
- for (const ix of initInstructions) {
7904
- if (ix) {
7905
- otherIxs.push(ix);
7906
- }
7907
- }
7908
- for (const tickData of tickAccounts) {
7909
- remainingAccounts.push({
7910
- pubkey: getTick(vaultId, tickData.tick, market),
7911
- isWritable: true,
7912
- isSigner: false
7913
- });
7914
- }
7915
- for (const tickHasDebtArray of tickHasDebt) {
7916
- remainingAccounts.push({
7917
- pubkey: getTickHasDebt(vaultId, tickHasDebtArray.index, market),
7918
- isWritable: true,
7919
- isSigner: false
7920
- });
7921
- }
7922
- const remainingAccountsIndices = [
7923
- oracleSources.length,
7924
- branches.length,
7925
- tickAccounts.length,
7926
- tickHasDebt.length
7927
- ];
7928
- return {
7929
- remainingAccounts,
7930
- otherIxs,
7931
- remainingAccountsIndices
7932
- };
7933
- }
7934
-
7935
- export { loadRelevantBranchesForLiquidate as A, loadRelevantTicksHasDebtArrays as B, loadRelevantTicksHasDebtArraysLiquidate as C, readOraclePrice as D, readTickHasDebtArray as E, vaultsIdl as F, INIT_TICK as I, MAX_REPAY_AMOUNT as M, TICKS_PER_TICK_HAS_DEBT as T, ZERO_TICK_SCALED_RATIO$1 as Z, getLiquidateIx as a, MAX_TICK$1 as b, MAX_WITHDRAW_AMOUNT as c, MIN_I128 as d, MIN_TICK$1 as e, TICK_HAS_DEBT_ARRAY_SIZE as f, getVaultsProgram as g, TICK_HAS_DEBT_CHILDREN_SIZE as h, TICK_HAS_DEBT_CHILDREN_SIZE_IN_BITS as i, TOTAL_INDICES_NEEDED as j, findNextTickWithDebt as k, getAccountOwner as l, getCurrentPosition as m, getCurrentPositionState as n, getFinalPosition as o, getFirstTickForIndex as p, getInitPositionContext as q, getInitPositionIx as r, getLiquidateContext as s, getLiquidityProgramId as t, getOperateContext as u, getOperateIx as v, getRatioAtTick as w, getTickAtRatio as x, getTickIndices as y, loadRelevantBranches as z };
6903
+ export { readTickHasDebtArray as A, reconcileLiquidatedDust as B, vaultsIdl as C, oracle as D, INIT_TICK as I, MAX_REPAY_AMOUNT as M, TICKS_PER_TICK_HAS_DEBT as T, ZERO_TICK_SCALED_RATIO$1 as Z, MAX_TICK$1 as a, MAX_WITHDRAW_AMOUNT as b, MIN_I128 as c, MIN_TICK$1 as d, TICK_HAS_DEBT_ARRAY_SIZE as e, TICK_HAS_DEBT_CHILDREN_SIZE as f, getVaultsProgram as g, TICK_HAS_DEBT_CHILDREN_SIZE_IN_BITS as h, TOTAL_INDICES_NEEDED as i, findNextTickWithDebt as j, getAccountOwner as k, getCurrentPosition as l, getCurrentPositionState as m, getFinalPosition as n, getFirstTickForIndex as o, getLiquidityProgramId as p, getMinimumDebt as q, getOracleSources as r, getRatioAtTick as s, getTickAtRatio as t, getTickIndices as u, loadRelevantBranches as v, loadRelevantBranchesForLiquidate as w, loadRelevantTicksHasDebtArrays as x, loadRelevantTicksHasDebtArraysLiquidate as y, readOraclePrice as z };