@velocity-exchange/sdk 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/README.md +3 -3
  2. package/lib/browser/adminClient.d.ts +35 -0
  3. package/lib/browser/adminClient.js +65 -0
  4. package/lib/browser/config.js +6 -7
  5. package/lib/browser/constants/numericConstants.d.ts +1 -1
  6. package/lib/browser/constants/numericConstants.js +1 -1
  7. package/lib/browser/decode/user.js +5 -1
  8. package/lib/browser/idl/velocity.d.ts +146 -3
  9. package/lib/browser/idl/velocity.json +147 -4
  10. package/lib/browser/orderSubscriber/OrderSubscriber.js +3 -0
  11. package/lib/browser/pyth/pythLazerSubscriber.js +37 -27
  12. package/lib/browser/types.d.ts +4 -0
  13. package/lib/browser/user.d.ts +15 -0
  14. package/lib/browser/user.js +37 -1
  15. package/lib/browser/velocityClient.d.ts +46 -10
  16. package/lib/browser/velocityClient.js +107 -35
  17. package/lib/node/adminClient.d.ts +35 -0
  18. package/lib/node/adminClient.d.ts.map +1 -1
  19. package/lib/node/adminClient.js +65 -0
  20. package/lib/node/config.d.ts.map +1 -1
  21. package/lib/node/config.js +6 -7
  22. package/lib/node/constants/numericConstants.d.ts +1 -1
  23. package/lib/node/constants/numericConstants.d.ts.map +1 -1
  24. package/lib/node/constants/numericConstants.js +1 -1
  25. package/lib/node/decode/user.d.ts.map +1 -1
  26. package/lib/node/decode/user.js +5 -1
  27. package/lib/node/idl/velocity.d.ts +146 -3
  28. package/lib/node/idl/velocity.d.ts.map +1 -1
  29. package/lib/node/idl/velocity.json +147 -4
  30. package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
  31. package/lib/node/orderSubscriber/OrderSubscriber.js +3 -0
  32. package/lib/node/pyth/pythLazerSubscriber.d.ts.map +1 -1
  33. package/lib/node/pyth/pythLazerSubscriber.js +37 -27
  34. package/lib/node/types.d.ts +4 -0
  35. package/lib/node/types.d.ts.map +1 -1
  36. package/lib/node/user.d.ts +15 -0
  37. package/lib/node/user.d.ts.map +1 -1
  38. package/lib/node/user.js +37 -1
  39. package/lib/node/velocityClient.d.ts +46 -10
  40. package/lib/node/velocityClient.d.ts.map +1 -1
  41. package/lib/node/velocityClient.js +107 -35
  42. package/package.json +7 -3
  43. package/.prettierignore +0 -1
  44. package/CHANGELOG.md +0 -132
  45. package/build-browser.js +0 -58
  46. package/bunfig.toml +0 -3
  47. package/esbuild-shims.js +0 -12
  48. package/scripts/deposit-isolated-positions.ts +0 -110
  49. package/scripts/find-flagged-users.ts +0 -213
  50. package/scripts/grpc-client-test-comparison.ts +0 -372
  51. package/scripts/grpc-multiuser-client-test-comparison.ts +0 -158
  52. package/scripts/postbuild.js +0 -95
  53. package/scripts/single-grpc-client-test.ts +0 -284
  54. package/scripts/withdraw-isolated-positions.ts +0 -174
  55. package/src/accounts/README_WebSocketAccountSubscriberV2.md +0 -95
  56. package/src/accounts/README_WebSocketProgramAccountSubscriberV2.md +0 -135
  57. package/src/accounts/basicUserAccountSubscriber.ts +0 -79
  58. package/src/accounts/basicUserStatsAccountSubscriber.ts +0 -87
  59. package/src/accounts/bulkAccountLoader.ts +0 -358
  60. package/src/accounts/bulkUserStatsSubscription.ts +0 -40
  61. package/src/accounts/bulkUserSubscription.ts +0 -39
  62. package/src/accounts/customizedCadenceBulkAccountLoader.ts +0 -250
  63. package/src/accounts/fetch.ts +0 -200
  64. package/src/accounts/grpcAccountSubscriber.ts +0 -225
  65. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -73
  66. package/src/accounts/grpcMultiAccountSubscriber.ts +0 -566
  67. package/src/accounts/grpcMultiUserAccountSubscriber.ts +0 -328
  68. package/src/accounts/grpcProgramAccountSubscriber.ts +0 -264
  69. package/src/accounts/grpcUserAccountSubscriber.ts +0 -63
  70. package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -65
  71. package/src/accounts/grpcVelocityClientAccountSubscriber.ts +0 -257
  72. package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +0 -941
  73. package/src/accounts/laserProgramAccountSubscriber.ts +0 -266
  74. package/src/accounts/oneShotUserAccountSubscriber.ts +0 -88
  75. package/src/accounts/oneShotUserStatsAccountSubscriber.ts +0 -94
  76. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -223
  77. package/src/accounts/pollingOracleAccountSubscriber.ts +0 -151
  78. package/src/accounts/pollingTokenAccountSubscriber.ts +0 -147
  79. package/src/accounts/pollingUserAccountSubscriber.ts +0 -198
  80. package/src/accounts/pollingUserStatsAccountSubscriber.ts +0 -180
  81. package/src/accounts/pollingVelocityClientAccountSubscriber.ts +0 -774
  82. package/src/accounts/testBulkAccountLoader.ts +0 -59
  83. package/src/accounts/types.ts +0 -428
  84. package/src/accounts/utils.ts +0 -90
  85. package/src/accounts/webSocketAccountSubscriber.ts +0 -304
  86. package/src/accounts/webSocketAccountSubscriberV2.ts +0 -536
  87. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +0 -171
  88. package/src/accounts/webSocketProgramAccountSubscriber.ts +0 -244
  89. package/src/accounts/webSocketProgramAccountSubscriberV2.ts +0 -1048
  90. package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +0 -1042
  91. package/src/accounts/webSocketUserAccountSubscriber.ts +0 -139
  92. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +0 -131
  93. package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +0 -865
  94. package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +0 -897
  95. package/src/accounts/websocketProgramUserAccountSubscriber.ts +0 -127
  96. package/src/addresses/marketAddresses.ts +0 -28
  97. package/src/addresses/pda.ts +0 -620
  98. package/src/adminClient.ts +0 -8136
  99. package/src/assert/assert.ts +0 -5
  100. package/src/auctionSubscriber/auctionSubscriber.ts +0 -86
  101. package/src/auctionSubscriber/auctionSubscriberGrpc.ts +0 -99
  102. package/src/auctionSubscriber/index.ts +0 -9
  103. package/src/auctionSubscriber/types.ts +0 -30
  104. package/src/bankrun/bankrunConnection.ts +0 -630
  105. package/src/blockhashSubscriber/BlockhashSubscriber.ts +0 -160
  106. package/src/blockhashSubscriber/index.ts +0 -6
  107. package/src/blockhashSubscriber/types.ts +0 -13
  108. package/src/clock/clockSubscriber.ts +0 -146
  109. package/src/config.ts +0 -312
  110. package/src/constants/index.ts +0 -9
  111. package/src/constants/numericConstants.ts +0 -194
  112. package/src/constants/perpMarkets.ts +0 -127
  113. package/src/constants/spotMarkets.ts +0 -104
  114. package/src/constants/txConstants.ts +0 -2
  115. package/src/constituentMap/constituentMap.ts +0 -305
  116. package/src/constituentMap/pollingConstituentAccountSubscriber.ts +0 -99
  117. package/src/constituentMap/webSocketConstituentAccountSubscriber.ts +0 -121
  118. package/src/core/VelocityCore.ts +0 -606
  119. package/src/core/index.ts +0 -12
  120. package/src/core/instructions/deposit.ts +0 -64
  121. package/src/core/instructions/fill.ts +0 -51
  122. package/src/core/instructions/funding.ts +0 -33
  123. package/src/core/instructions/liquidation.ts +0 -55
  124. package/src/core/instructions/orders.ts +0 -84
  125. package/src/core/instructions/perpOrders.ts +0 -312
  126. package/src/core/instructions/settlement.ts +0 -40
  127. package/src/core/instructions/trigger.ts +0 -41
  128. package/src/core/instructions/withdraw.ts +0 -65
  129. package/src/core/remainingAccounts.ts +0 -320
  130. package/src/core/signedMsg.ts +0 -109
  131. package/src/decode/customCoder.ts +0 -148
  132. package/src/decode/user.ts +0 -401
  133. package/src/dlob/DLOB.ts +0 -2793
  134. package/src/dlob/DLOBNode.ts +0 -305
  135. package/src/dlob/DLOBSubscriber.ts +0 -269
  136. package/src/dlob/NodeList.ts +0 -244
  137. package/src/dlob/orderBookLevels.ts +0 -695
  138. package/src/dlob/types.ts +0 -37
  139. package/src/events/eventList.ts +0 -114
  140. package/src/events/eventSubscriber.ts +0 -521
  141. package/src/events/eventsServerLogProvider.ts +0 -189
  142. package/src/events/fetchLogs.ts +0 -219
  143. package/src/events/parse.ts +0 -271
  144. package/src/events/pollingLogProvider.ts +0 -113
  145. package/src/events/sort.ts +0 -51
  146. package/src/events/txEventCache.ts +0 -92
  147. package/src/events/types.ts +0 -337
  148. package/src/events/webSocketLogProvider.ts +0 -152
  149. package/src/factory/bigNum.ts +0 -709
  150. package/src/factory/oracleClient.ts +0 -73
  151. package/src/idl/pyth.json +0 -142
  152. package/src/idl/pyth.ts +0 -97
  153. package/src/idl/pyth_solana_receiver.json +0 -628
  154. package/src/idl/token_faucet.json +0 -229
  155. package/src/idl/token_faucet.ts +0 -197
  156. package/src/idl/velocity.json +0 -23974
  157. package/src/idl/velocity.ts +0 -23980
  158. package/src/index.ts +0 -150
  159. package/src/indicative-quotes/indicativeQuotesSender.ts +0 -233
  160. package/src/isomorphic/README.md +0 -19
  161. package/src/isomorphic/anchor.browser.ts +0 -44
  162. package/src/isomorphic/anchor.node.ts +0 -1
  163. package/src/isomorphic/anchor.ts +0 -1
  164. package/src/isomorphic/anchor29.browser.ts +0 -24
  165. package/src/isomorphic/anchor29.node.ts +0 -1
  166. package/src/isomorphic/anchor29.ts +0 -1
  167. package/src/isomorphic/grpc.browser.ts +0 -4
  168. package/src/isomorphic/grpc.node.ts +0 -130
  169. package/src/isomorphic/grpc.ts +0 -1
  170. package/src/jupiter/jupiterClient.ts +0 -502
  171. package/src/keypair.ts +0 -32
  172. package/src/margin/README.md +0 -138
  173. package/src/marginCalculation.ts +0 -407
  174. package/src/marinade/idl/idl.json +0 -1962
  175. package/src/marinade/index.ts +0 -73
  176. package/src/marinade/types.ts +0 -3925
  177. package/src/math/amm.ts +0 -1758
  178. package/src/math/auction.ts +0 -480
  179. package/src/math/bankruptcy.ts +0 -138
  180. package/src/math/builder.ts +0 -130
  181. package/src/math/conversion.ts +0 -45
  182. package/src/math/exchangeStatus.ts +0 -261
  183. package/src/math/funding.ts +0 -498
  184. package/src/math/insurance.ts +0 -171
  185. package/src/math/liquidation.ts +0 -433
  186. package/src/math/margin.ts +0 -327
  187. package/src/math/market.ts +0 -487
  188. package/src/math/oracles.ts +0 -477
  189. package/src/math/orders.ts +0 -500
  190. package/src/math/position.ts +0 -381
  191. package/src/math/repeg.ts +0 -223
  192. package/src/math/spotBalance.ts +0 -996
  193. package/src/math/spotMarket.ts +0 -115
  194. package/src/math/spotPosition.ts +0 -263
  195. package/src/math/state.ts +0 -71
  196. package/src/math/superStake.ts +0 -602
  197. package/src/math/tiers.ts +0 -73
  198. package/src/math/trade.ts +0 -879
  199. package/src/math/utils.ts +0 -183
  200. package/src/memcmp.ts +0 -279
  201. package/src/oracles/oracleClientCache.ts +0 -41
  202. package/src/oracles/oracleId.ts +0 -99
  203. package/src/oracles/prelaunchOracleClient.ts +0 -63
  204. package/src/oracles/pythClient.ts +0 -125
  205. package/src/oracles/pythLazerClient.ts +0 -141
  206. package/src/oracles/quoteAssetOracleClient.ts +0 -43
  207. package/src/oracles/strictOraclePrice.ts +0 -40
  208. package/src/oracles/types.ts +0 -82
  209. package/src/oracles/utils.ts +0 -45
  210. package/src/orderParams.ts +0 -117
  211. package/src/orderSubscriber/OrderSubscriber.ts +0 -378
  212. package/src/orderSubscriber/PollingSubscription.ts +0 -50
  213. package/src/orderSubscriber/WebsocketSubscription.ts +0 -137
  214. package/src/orderSubscriber/grpcSubscription.ts +0 -155
  215. package/src/orderSubscriber/index.ts +0 -7
  216. package/src/orderSubscriber/types.ts +0 -64
  217. package/src/priorityFee/averageOverSlotsStrategy.ts +0 -17
  218. package/src/priorityFee/averageStrategy.ts +0 -13
  219. package/src/priorityFee/ewmaStrategy.ts +0 -51
  220. package/src/priorityFee/heliusPriorityFeeMethod.ts +0 -68
  221. package/src/priorityFee/index.ts +0 -16
  222. package/src/priorityFee/maxOverSlotsStrategy.ts +0 -18
  223. package/src/priorityFee/maxStrategy.ts +0 -8
  224. package/src/priorityFee/priorityFeeSubscriber.ts +0 -328
  225. package/src/priorityFee/priorityFeeSubscriberMap.ts +0 -134
  226. package/src/priorityFee/solanaPriorityFeeMethod.ts +0 -46
  227. package/src/priorityFee/types.ts +0 -82
  228. package/src/priorityFee/velocityPriorityFeeMethod.ts +0 -53
  229. package/src/pyth/constants.ts +0 -9
  230. package/src/pyth/index.ts +0 -15
  231. package/src/pyth/pythLazerSubscriber.ts +0 -365
  232. package/src/pyth/types.ts +0 -4451
  233. package/src/pyth/utils.ts +0 -13
  234. package/src/slot/SlotSubscriber.ts +0 -126
  235. package/src/slot/SlothashSubscriber.ts +0 -163
  236. package/src/swap/UnifiedSwapClient.ts +0 -315
  237. package/src/swift/grpcSignedMsgUserAccountSubscriber.ts +0 -81
  238. package/src/swift/index.ts +0 -10
  239. package/src/swift/signedMsgUserAccountSubscriber.ts +0 -251
  240. package/src/swift/swiftOrderSubscriber.ts +0 -351
  241. package/src/testClient.ts +0 -42
  242. package/src/titan/titanClient.ts +0 -438
  243. package/src/token/index.ts +0 -13
  244. package/src/tokenFaucet.ts +0 -296
  245. package/src/tx/baseTxSender.ts +0 -651
  246. package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +0 -31
  247. package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +0 -105
  248. package/src/tx/blockhashFetcher/types.ts +0 -9
  249. package/src/tx/fastSingleTxSender.ts +0 -200
  250. package/src/tx/forwardOnlyTxSender.ts +0 -193
  251. package/src/tx/priorityFeeCalculator.ts +0 -117
  252. package/src/tx/reportTransactionError.ts +0 -176
  253. package/src/tx/retryTxSender.ts +0 -177
  254. package/src/tx/txHandler.ts +0 -1009
  255. package/src/tx/txParamProcessor.ts +0 -225
  256. package/src/tx/types.ts +0 -117
  257. package/src/tx/utils.ts +0 -133
  258. package/src/tx/whileValidTxSender.ts +0 -377
  259. package/src/types.ts +0 -2575
  260. package/src/user.ts +0 -5316
  261. package/src/userConfig.ts +0 -38
  262. package/src/userMap/PollingSubscription.ts +0 -61
  263. package/src/userMap/WebsocketSubscription.ts +0 -93
  264. package/src/userMap/grpcSubscription.ts +0 -93
  265. package/src/userMap/referrerMap.ts +0 -360
  266. package/src/userMap/revenueShareEscrowMap.ts +0 -342
  267. package/src/userMap/userMap.ts +0 -784
  268. package/src/userMap/userMapConfig.ts +0 -82
  269. package/src/userMap/userStatsMap.ts +0 -393
  270. package/src/userName.ts +0 -37
  271. package/src/userStats.ts +0 -159
  272. package/src/userStatsConfig.ts +0 -35
  273. package/src/util/TransactionConfirmationManager.ts +0 -333
  274. package/src/util/chainClock.ts +0 -65
  275. package/src/util/computeUnits.ts +0 -101
  276. package/src/util/digest.ts +0 -33
  277. package/src/util/ed25519Utils.ts +0 -95
  278. package/src/util/promiseTimeout.ts +0 -23
  279. package/src/velocityClient.ts +0 -14802
  280. package/src/velocityClientConfig.ts +0 -119
  281. package/src/wallet.ts +0 -91
  282. package/tests/VelocityCore/builder_escrow.test.ts +0 -121
  283. package/tests/VelocityCore/decode.test.ts +0 -16
  284. package/tests/VelocityCore/fill_trigger.test.ts +0 -73
  285. package/tests/VelocityCore/instructions.test.ts +0 -46
  286. package/tests/VelocityCore/pdas.test.ts +0 -30
  287. package/tests/VelocityCore/perp_orders.test.ts +0 -205
  288. package/tests/VelocityCore/remainingAccounts.test.ts +0 -72
  289. package/tests/VelocityCore/settlement_liquidation.test.ts +0 -69
  290. package/tests/accounts/customizedCadenceBulkAccountLoader.test.ts +0 -211
  291. package/tests/amm/test.ts +0 -2402
  292. package/tests/auctions/test.ts +0 -81
  293. package/tests/bn/test.ts +0 -355
  294. package/tests/builder/builderFee.test.ts +0 -42
  295. package/tests/ci/verifyConstants.ts +0 -393
  296. package/tests/decode/test.ts +0 -262
  297. package/tests/decode/userAccountBufferStrings.ts +0 -102
  298. package/tests/dlob/helpers.ts +0 -748
  299. package/tests/dlob/test.ts +0 -6969
  300. package/tests/dlob/tickSizeStandardization.ts +0 -545
  301. package/tests/events/parseLogsForCuUsage.ts +0 -139
  302. package/tests/exchangeStatus/test.ts +0 -45
  303. package/tests/insurance/test.ts +0 -40
  304. package/tests/liquidation/test.ts +0 -125
  305. package/tests/oracles/mmOracleGate.test.ts +0 -379
  306. package/tests/oracles/pythPegSnap.test.ts +0 -76
  307. package/tests/sdkParity/enumParity.test.ts +0 -84
  308. package/tests/sdkParity/marginCategoryFill.test.ts +0 -143
  309. package/tests/sdkParity/memcmpOffsets.test.ts +0 -139
  310. package/tests/spot/test.ts +0 -281
  311. package/tests/tx/TransactionConfirmationManager.test.ts +0 -312
  312. package/tests/tx/cachedBlockhashFetcher.test.ts +0 -96
  313. package/tests/tx/priorityFeeCalculator.ts +0 -77
  314. package/tests/tx/priorityFeeStrategy.ts +0 -95
  315. package/tests/user/bankruptcy.ts +0 -165
  316. package/tests/user/feeAndWithdrawLimits.ts +0 -284
  317. package/tests/user/getMarginCalculation.ts +0 -586
  318. package/tests/user/helpers.ts +0 -184
  319. package/tests/user/liquidations.ts +0 -129
  320. package/tests/user/marginCalculations.test.ts +0 -321
  321. package/tests/user/test.ts +0 -833
  322. package/tsconfig.browser.json +0 -18
  323. package/tsconfig.json +0 -36
@@ -1,433 +0,0 @@
1
- import { BN } from '../isomorphic/anchor';
2
- import {
3
- PRICE_PRECISION,
4
- LIQUIDATION_FEE_PRECISION,
5
- MARGIN_PRECISION,
6
- PRICE_TIMES_AMM_TO_QUOTE_PRECISION_RATIO,
7
- QUOTE_PRECISION,
8
- LIQUIDATION_PCT_PRECISION,
9
- SPOT_MARKET_WEIGHT_PRECISION,
10
- BASE_PRECISION,
11
- TEN,
12
- ONE,
13
- ZERO,
14
- } from '../constants/numericConstants';
15
-
16
- /**
17
- * Calculates the base asset amount a liquidator must take from a perp position to cover a
18
- * given margin shortage, mirroring `calculate_base_asset_amount_to_cover_margin_shortage` in
19
- * `programs/velocity/src/math/liquidation.rs`. Larger `marginRatio`/`liquidationFee` spread
20
- * (the liquidator's margin) means less base asset amount is needed per dollar of shortage
21
- * covered; the `ifLiquidationFee` cut is subtracted from the liquidator's proceeds first.
22
- * @param marginShortage Margin shortfall to cover, QUOTE_PRECISION (1e6).
23
- * @param marginRatio Position's maintenance margin ratio, MARGIN_PRECISION (1e4).
24
- * @param liquidationFee Liquidator's fee rate, LIQUIDATION_FEE_PRECISION (1e6).
25
- * @param ifLiquidationFee The margin-shortage-aware insurance-side fee, i.e. the
26
- * output of `calculatePerpIfFee` (which is itself capped at
27
- * `market.ifLiquidationFee + market.protocolLiquidationFee`). Pass that
28
- * computed value here, not the raw `ifLiquidationFee + protocolLiquidationFee`
29
- * sum — the on-chain sizing uses the capped, shortage-aware amount.
30
- * @param oraclePrice Oracle price of the perp market, PRICE_PRECISION (1e6).
31
- * @param quoteOraclePrice Oracle price of the quote asset, PRICE_PRECISION (1e6).
32
- * @returns Base asset amount to transfer, BASE_PRECISION (1e9); `undefined` means "no finite
33
- * amount can cover the shortage" (oracle price is zero, or the margin ratio doesn't exceed
34
- * the liquidation fee) — treat as unbounded/take the whole position.
35
- */
36
- export function calculateBaseAssetAmountToCoverMarginShortage(
37
- marginShortage: BN,
38
- marginRatio: number,
39
- liquidationFee: number,
40
- ifLiquidationFee: number,
41
- oraclePrice: BN,
42
- quoteOraclePrice: BN
43
- ): BN | undefined {
44
- const marginRatioBN = new BN(marginRatio)
45
- .mul(LIQUIDATION_FEE_PRECISION)
46
- .div(MARGIN_PRECISION);
47
- const liquidationFeeBN = new BN(liquidationFee);
48
-
49
- if (oraclePrice.eq(new BN(0)) || marginRatioBN.lte(liquidationFeeBN)) {
50
- // undefined is max
51
- return undefined;
52
- }
53
-
54
- return marginShortage.mul(PRICE_TIMES_AMM_TO_QUOTE_PRECISION_RATIO).div(
55
- oraclePrice
56
- .mul(quoteOraclePrice)
57
- .div(PRICE_PRECISION)
58
- .mul(marginRatioBN.sub(liquidationFeeBN))
59
- .div(LIQUIDATION_FEE_PRECISION)
60
- .sub(
61
- oraclePrice.mul(new BN(ifLiquidationFee)).div(LIQUIDATION_FEE_PRECISION)
62
- )
63
- );
64
- }
65
-
66
- /**
67
- * Calculates the spot liability token amount a liquidator must take to cover a given margin
68
- * shortage, mirroring `calculate_liability_transfer_to_cover_margin_shortage` in
69
- * `programs/velocity/src/math/liquidation.rs`. Scales with the gap between the asset and
70
- * liability weights (adjusted by their respective liquidation multipliers) — a wider spread
71
- * means less liability token amount is needed per dollar of shortage covered.
72
- * @param marginShortage Margin shortfall to cover, QUOTE_PRECISION (1e6).
73
- * @param assetWeight Weight of the collateral asset the liquidator gives up, SPOT_MARKET_WEIGHT_PRECISION (1e4).
74
- * @param assetLiquidationMultiplier Liquidation-time discount multiplier on the asset side, LIQUIDATION_FEE_PRECISION (1e6).
75
- * @param liabilityWeight Weight of the liability being repaid, SPOT_MARKET_WEIGHT_PRECISION (1e4).
76
- * @param liabilityLiquidationMultiplier Liquidation-time premium multiplier on the liability side, LIQUIDATION_FEE_PRECISION (1e6).
77
- * @param liabilityDecimals Liability spot market's token decimals.
78
- * @param liabilityPrice Oracle price of the liability asset, PRICE_PRECISION (1e6).
79
- * @param ifLiquidationFee The margin-shortage-aware insurance-side fee, i.e. the
80
- * output of `calculateSpotIfFee` (which is itself capped at
81
- * `liabilityMarket.ifLiquidationFee + liabilityMarket.protocolLiquidationFee`).
82
- * Pass that computed value here, not the raw sum of the two rates — the
83
- * on-chain sizing uses the capped, shortage-aware amount.
84
- * @returns Liability token amount to transfer, in the liability spot market's own token
85
- * precision (`10^liabilityDecimals`); `undefined` means "no finite amount can cover the
86
- * shortage" (`assetWeight >= liabilityWeight`, or the effective spread is non-positive) —
87
- * treat as unbounded/take the whole liability.
88
- */
89
- export function calculateLiabilityTransferToCoverMarginShortage(
90
- marginShortage: BN,
91
- assetWeight: number,
92
- assetLiquidationMultiplier: number,
93
- liabilityWeight: number,
94
- liabilityLiquidationMultiplier: number,
95
- liabilityDecimals: number,
96
- liabilityPrice: BN,
97
- ifLiquidationFee: number
98
- ): BN | undefined {
99
- if (assetWeight >= liabilityWeight) {
100
- // undefined is max
101
- return undefined;
102
- }
103
-
104
- let numeratorScale: BN;
105
- let denominatorScale: BN;
106
- if (liabilityDecimals > 6) {
107
- numeratorScale = new BN(10).pow(new BN(liabilityDecimals - 6));
108
- denominatorScale = new BN(1);
109
- } else {
110
- numeratorScale = new BN(1);
111
- denominatorScale = new BN(10).pow(new BN(6 - liabilityDecimals));
112
- }
113
-
114
- // multiply market weights by extra 10 to increase precision
115
- const liabilityWeightComponent = liabilityWeight * 10;
116
- const assetWeightComponent =
117
- (assetWeight * 10 * assetLiquidationMultiplier) /
118
- liabilityLiquidationMultiplier;
119
-
120
- if (assetWeightComponent >= liabilityWeightComponent) {
121
- return undefined;
122
- }
123
-
124
- return BN.max(
125
- marginShortage
126
- .mul(numeratorScale)
127
- .mul(PRICE_PRECISION.mul(SPOT_MARKET_WEIGHT_PRECISION).mul(TEN))
128
- .div(
129
- liabilityPrice
130
- .mul(
131
- new BN(liabilityWeightComponent).sub(new BN(assetWeightComponent))
132
- )
133
- .sub(
134
- liabilityPrice
135
- .mul(new BN(ifLiquidationFee))
136
- .div(LIQUIDATION_FEE_PRECISION)
137
- .mul(new BN(liabilityWeight))
138
- .mul(new BN(10))
139
- )
140
- )
141
- .div(denominatorScale),
142
- ONE
143
- );
144
- }
145
-
146
- /**
147
- * Calculates the margin-shortage-aware insurance-fund fee for liquidating a perp position,
148
- * mirroring `calculate_perp_if_fee` in `programs/velocity/src/math/liquidation.rs`. Starts
149
- * from `marginRatio - liquidatorFee` (the room left after the liquidator's own cut) and
150
- * subtracts a shortage-proportional deduction so the IF fee shrinks as the shortage grows
151
- * relative to position value — this is the "shortage-aware" behavior referenced by
152
- * `calculateBaseAssetAmountToCoverMarginShortage`'s `ifLiquidationFee` param. The result is
153
- * further scaled by 95% (to avoid the fee itself pushing the user into bankruptcy) and capped
154
- * at `maxIfLiquidationFee` (typically `market.ifLiquidationFee + market.protocolLiquidationFee`).
155
- * @param marginShortage Margin shortfall being covered, QUOTE_PRECISION (1e6).
156
- * @param userBaseAssetAmount Base amount being liquidated, BASE_PRECISION (1e9, signed — only magnitude matters).
157
- * @param marginRatio Position's maintenance margin ratio, MARGIN_PRECISION (1e4).
158
- * @param liquidatorFee Liquidator's fee rate, LIQUIDATION_FEE_PRECISION (1e6).
159
- * @param oraclePrice Oracle price of the perp market, PRICE_PRECISION (1e6).
160
- * @param quoteOraclePrice Oracle price of the quote asset, PRICE_PRECISION (1e6).
161
- * @param maxIfLiquidationFee Upper bound on the returned fee, LIQUIDATION_FEE_PRECISION (1e6).
162
- * @returns Insurance-fund fee rate, LIQUIDATION_FEE_PRECISION (1e6); `0` if either oracle
163
- * price is zero, the position size is zero, or `marginRatio` doesn't exceed `liquidatorFee`.
164
- */
165
- export function calculatePerpIfFee(
166
- marginShortage: BN,
167
- userBaseAssetAmount: BN,
168
- marginRatio: number,
169
- liquidatorFee: number,
170
- oraclePrice: BN,
171
- quoteOraclePrice: BN,
172
- maxIfLiquidationFee: number
173
- ): number {
174
- const marginRatioBN = new BN(marginRatio).mul(
175
- LIQUIDATION_FEE_PRECISION.div(MARGIN_PRECISION)
176
- );
177
-
178
- if (
179
- oraclePrice.eq(ZERO) ||
180
- quoteOraclePrice.eq(ZERO) ||
181
- marginRatioBN.lte(new BN(liquidatorFee)) ||
182
- userBaseAssetAmount.eq(ZERO)
183
- ) {
184
- return 0;
185
- }
186
-
187
- const price = oraclePrice.mul(quoteOraclePrice).div(PRICE_PRECISION);
188
-
189
- // margin ratio - liquidator fee - (margin shortage / (user base asset amount * price))
190
- // the program receives base_asset_amount.unsigned_abs() (u64), so only the magnitude
191
- // participates in the shortage term
192
- let impliedIfFee = BN.max(marginRatioBN.sub(new BN(liquidatorFee)), ZERO);
193
- const shortageComponent = marginShortage
194
- .mul(BASE_PRECISION)
195
- .div(userBaseAssetAmount.abs())
196
- .mul(PRICE_PRECISION)
197
- .div(price);
198
- impliedIfFee = BN.max(impliedIfFee.sub(shortageComponent), ZERO);
199
-
200
- // multiply by 95% to avoid situation where fee leads to deposits == negative pnl
201
- // leading to bankruptcy
202
- impliedIfFee = impliedIfFee.mul(new BN(19)).div(new BN(20));
203
-
204
- return BN.min(new BN(maxIfLiquidationFee), impliedIfFee).toNumber();
205
- }
206
-
207
- /**
208
- * Calculates the margin-shortage-aware insurance-fund fee for a spot liability liquidation,
209
- * mirroring `calculate_spot_if_fee` in `programs/velocity/src/math/liquidation.rs`. Same
210
- * shortage-aware shape as `calculatePerpIfFee`: starts from the asset/liability weight
211
- * spread (scaled by their liquidation multipliers), subtracts a shortage-proportional
212
- * deduction, and caps at `maxIfFee` (typically `liabilityMarket.ifLiquidationFee +
213
- * liabilityMarket.protocolLiquidationFee`).
214
- * @param marginShortage Margin shortfall being covered, QUOTE_PRECISION (1e6).
215
- * @param tokenAmount Liability token amount being liquidated, liability spot market's own token precision (`10^liabilityDecimals`).
216
- * @param assetWeight Weight of the collateral asset the liquidator gives up, SPOT_MARKET_WEIGHT_PRECISION (1e4).
217
- * @param assetLiquidationMultiplier Liquidation-time discount multiplier on the asset side, LIQUIDATION_FEE_PRECISION (1e6).
218
- * @param liabilityWeight Weight of the liability being repaid, SPOT_MARKET_WEIGHT_PRECISION (1e4).
219
- * @param liabilityLiquidationMultiplier Liquidation-time premium multiplier on the liability side, LIQUIDATION_FEE_PRECISION (1e6).
220
- * @param liabilityDecimals Liability spot market's token decimals.
221
- * @param liabilityPrice Oracle price of the liability asset, PRICE_PRECISION (1e6).
222
- * @param maxIfFee Upper bound on the returned fee, LIQUIDATION_FEE_PRECISION (1e6).
223
- * @returns Insurance-fund fee rate, LIQUIDATION_FEE_PRECISION (1e6); `0` if
224
- * `assetWeight >= liabilityWeight`, the liability price/token amount is zero, or
225
- * `liabilityLiquidationMultiplier` is zero.
226
- */
227
- export function calculateSpotIfFee(
228
- marginShortage: BN,
229
- tokenAmount: BN,
230
- assetWeight: number,
231
- assetLiquidationMultiplier: number,
232
- liabilityWeight: number,
233
- liabilityLiquidationMultiplier: number,
234
- liabilityDecimals: number,
235
- liabilityPrice: BN,
236
- maxIfFee: number
237
- ): number {
238
- if (
239
- assetWeight >= liabilityWeight ||
240
- liabilityPrice.eq(ZERO) ||
241
- tokenAmount.eq(ZERO) ||
242
- liabilityLiquidationMultiplier === 0
243
- ) {
244
- return 0;
245
- }
246
-
247
- const tokenPrecision = TEN.pow(new BN(liabilityDecimals));
248
-
249
- const weightPrecisionRatio = LIQUIDATION_FEE_PRECISION.div(
250
- SPOT_MARKET_WEIGHT_PRECISION
251
- );
252
- const liabilityWeightBN = new BN(liabilityWeight).mul(weightPrecisionRatio);
253
- const assetWeightBN = new BN(assetWeight).mul(weightPrecisionRatio);
254
-
255
- let impliedIfFee = BN.max(
256
- liabilityWeightBN.sub(
257
- assetWeightBN
258
- .mul(new BN(assetLiquidationMultiplier))
259
- .div(new BN(liabilityLiquidationMultiplier))
260
- ),
261
- ZERO
262
- );
263
-
264
- const shortageComponent = marginShortage
265
- .mul(LIQUIDATION_FEE_PRECISION)
266
- .mul(tokenPrecision)
267
- .div(tokenAmount)
268
- .div(liabilityPrice);
269
- impliedIfFee = BN.max(impliedIfFee.sub(shortageComponent), ZERO);
270
-
271
- impliedIfFee = impliedIfFee
272
- .mul(LIQUIDATION_FEE_PRECISION)
273
- .div(liabilityWeightBN);
274
-
275
- return BN.min(new BN(maxIfFee), impliedIfFee).toNumber();
276
- }
277
-
278
- /**
279
- * Calculates how much of a liquidated user's collateral asset a liquidator receives in
280
- * exchange for repaying `liabilityAmount` of a liability, mirroring
281
- * `calculate_asset_transfer_for_liability_transfer` in
282
- * `programs/velocity/src/math/liquidation.rs`. Converts the liability amount to an
283
- * equivalent asset amount at the two assets' oracle prices, scaled by their respective
284
- * liquidation multipliers (the premium/discount applied at liquidation), then rounds up to
285
- * the user's full remaining asset balance (`assetAmount`) if the difference is under
286
- * `QUOTE_PRECISION` (1e6) worth of value — avoiding dust asset balances left behind.
287
- * @param assetAmount User's available balance of the asset being transferred, asset spot market's own token precision.
288
- * @param assetLiquidationMultiplier Liquidation-time discount multiplier on the asset side, LIQUIDATION_FEE_PRECISION (1e6).
289
- * @param assetDecimals Asset spot market's token decimals.
290
- * @param assetPrice Oracle price of the asset, PRICE_PRECISION (1e6).
291
- * @param liabilityAmount Liability amount being repaid, liability spot market's own token precision.
292
- * @param liabilityLiquidationMultiplier Liquidation-time premium multiplier on the liability side, LIQUIDATION_FEE_PRECISION (1e6).
293
- * @param liabilityDecimals Liability spot market's token decimals.
294
- * @param liabilityPrice Oracle price of the liability asset, PRICE_PRECISION (1e6).
295
- * @returns Asset amount to transfer to the liquidator, asset spot market's own token precision (floored at 1).
296
- */
297
- export function calculateAssetTransferForLiabilityTransfer(
298
- assetAmount: BN,
299
- assetLiquidationMultiplier: number,
300
- assetDecimals: number,
301
- assetPrice: BN,
302
- liabilityAmount: BN,
303
- liabilityLiquidationMultiplier: number,
304
- liabilityDecimals: number,
305
- liabilityPrice: BN
306
- ): BN | undefined {
307
- let numeratorScale: BN;
308
- let denominatorScale: BN;
309
- if (assetDecimals > liabilityDecimals) {
310
- numeratorScale = new BN(10).pow(new BN(assetDecimals - liabilityDecimals));
311
- denominatorScale = new BN(1);
312
- } else {
313
- numeratorScale = new BN(1);
314
- denominatorScale = new BN(10).pow(
315
- new BN(liabilityDecimals - assetDecimals)
316
- );
317
- }
318
-
319
- let assetTransfer = liabilityAmount
320
- .mul(numeratorScale)
321
- .mul(liabilityPrice)
322
- .mul(new BN(assetLiquidationMultiplier))
323
- .div(assetPrice.mul(new BN(liabilityLiquidationMultiplier)))
324
- .div(denominatorScale);
325
- assetTransfer = BN.max(assetTransfer, ONE);
326
-
327
- // Need to check if asset_transfer should be rounded to asset amount
328
- let assetValueNumeratorScale: BN;
329
- let assetValueDenominatorScale: BN;
330
- if (assetDecimals > 6) {
331
- assetValueNumeratorScale = new BN(10).pow(new BN(assetDecimals - 6));
332
- assetValueDenominatorScale = new BN(1);
333
- } else {
334
- assetValueNumeratorScale = new BN(1);
335
- assetValueDenominatorScale = new BN(10).pow(new BN(6 - assetDecimals));
336
- }
337
-
338
- let assetDelta: BN;
339
- if (assetTransfer > assetAmount) {
340
- assetDelta = assetTransfer.sub(assetAmount);
341
- } else {
342
- assetDelta = assetAmount.sub(assetTransfer);
343
- }
344
-
345
- const assetValueDelta = assetDelta
346
- .mul(assetPrice)
347
- .div(PRICE_PRECISION)
348
- .mul(assetValueNumeratorScale)
349
- .div(assetValueDenominatorScale);
350
-
351
- if (assetValueDelta.lt(QUOTE_PRECISION)) {
352
- assetTransfer = assetAmount;
353
- }
354
-
355
- return assetTransfer;
356
- }
357
-
358
- /**
359
- * Calculates the fraction of a position's remaining liability a liquidator may currently
360
- * take, mirroring `calculate_max_pct_to_liquidate` in
361
- * `programs/velocity/src/math/liquidation.rs`. Liquidations ramp up gradually over
362
- * `liquidationDuration` slots (starting from `initialPctToLiquidate`) rather than allowing
363
- * 100% in one shot, so a user isn't force-closed more aggressively than necessary — except:
364
- * isolated perp positions (`isIsolatedPosition`) are always liquidated 100% in one shot
365
- * since they have no other cross-margin exposure to protect, and any position is liquidated
366
- * 100% immediately once `marginShortage` is under $50 (dust threshold, not worth ramping).
367
- * @param userLastActiveSlot Slot the user was last active (start of the liquidation ramp), used with `slot` to compute elapsed time.
368
- * @param userLiquidationMarginFreed Margin already freed by liquidation actions so far this liquidation, QUOTE_PRECISION (1e6).
369
- * @param marginShortage Total margin shortfall for the user/position, QUOTE_PRECISION (1e6).
370
- * @param slot Current slot.
371
- * @param initialPctToLiquidate Starting liquidatable fraction at slot zero of the ramp, LIQUIDATION_PCT_PRECISION (1e4).
372
- * @param liquidationDuration Number of slots for the ramp to reach 100% (~1 minute at 400ms/slot for the on-chain default).
373
- * @param isIsolatedPosition If true, always returns 100% (LIQUIDATION_PCT_PRECISION) regardless of the other inputs (default false).
374
- * @returns Fraction of the remaining liability liquidatable now, LIQUIDATION_PCT_PRECISION (1e4).
375
- */
376
- export function calculateMaxPctToLiquidate(
377
- userLastActiveSlot: BN,
378
- userLiquidationMarginFreed: BN,
379
- marginShortage: BN,
380
- slot: BN,
381
- initialPctToLiquidate: BN,
382
- liquidationDuration: BN,
383
- isIsolatedPosition = false
384
- ): BN {
385
- // isolated perp positions are liquidated 100% in one shot
386
- if (isIsolatedPosition) {
387
- return LIQUIDATION_PCT_PRECISION;
388
- }
389
-
390
- // if margin shortage is tiny, accelerate liquidation
391
- if (marginShortage.lt(new BN(50).mul(QUOTE_PRECISION))) {
392
- return LIQUIDATION_PCT_PRECISION;
393
- }
394
-
395
- const slotsElapsed = BN.max(slot.sub(userLastActiveSlot), new BN(0));
396
-
397
- const pctFreeable = BN.min(
398
- slotsElapsed
399
- .mul(LIQUIDATION_PCT_PRECISION)
400
- .div(liquidationDuration) // ~ 1 minute if per slot is 400ms
401
- .add(initialPctToLiquidate),
402
- LIQUIDATION_PCT_PRECISION
403
- );
404
-
405
- const totalMarginShortage = marginShortage.add(userLiquidationMarginFreed);
406
- const maxMarginFreed = totalMarginShortage
407
- .mul(pctFreeable)
408
- .div(LIQUIDATION_PCT_PRECISION);
409
- const marginFreeable = BN.max(
410
- maxMarginFreed.sub(userLiquidationMarginFreed),
411
- new BN(0)
412
- );
413
-
414
- return marginFreeable.mul(LIQUIDATION_PCT_PRECISION).div(marginShortage);
415
- }
416
-
417
- /**
418
- * Absolute margin shortfall between a (buffered) maintenance margin requirement and total
419
- * collateral. Returns a positive magnitude regardless of which side is larger — callers
420
- * typically only call this once `meetsMarginRequirementWithBuffer()` has already returned
421
- * `false`, at which point the result is the true shortage to cover.
422
- * @param maintenanceMarginRequirementPlusBuffer Buffered maintenance margin requirement, QUOTE_PRECISION (1e6).
423
- * @param maintenanceTotalCollateral Total collateral at maintenance weights, QUOTE_PRECISION (1e6).
424
- * @returns `abs(maintenanceMarginRequirementPlusBuffer - maintenanceTotalCollateral)`, QUOTE_PRECISION (1e6).
425
- */
426
- export function getMarginShortage(
427
- maintenanceMarginRequirementPlusBuffer: BN,
428
- maintenanceTotalCollateral: BN
429
- ): BN {
430
- return maintenanceMarginRequirementPlusBuffer
431
- .sub(maintenanceTotalCollateral)
432
- .abs();
433
- }