@velocity-exchange/sdk 0.4.0 → 0.6.1

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 (325) hide show
  1. package/README.md +3 -3
  2. package/lib/browser/adminClient.d.ts +52 -0
  3. package/lib/browser/adminClient.js +97 -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 +191 -15
  9. package/lib/browser/idl/velocity.json +192 -16
  10. package/lib/browser/orderSubscriber/OrderSubscriber.d.ts +1 -0
  11. package/lib/browser/orderSubscriber/OrderSubscriber.js +10 -4
  12. package/lib/browser/pyth/pythLazerSubscriber.js +37 -27
  13. package/lib/browser/types.d.ts +6 -0
  14. package/lib/browser/user.d.ts +20 -3
  15. package/lib/browser/user.js +52 -4
  16. package/lib/browser/velocityClient.d.ts +46 -10
  17. package/lib/browser/velocityClient.js +107 -35
  18. package/lib/node/adminClient.d.ts +52 -0
  19. package/lib/node/adminClient.d.ts.map +1 -1
  20. package/lib/node/adminClient.js +97 -0
  21. package/lib/node/config.d.ts.map +1 -1
  22. package/lib/node/config.js +6 -7
  23. package/lib/node/constants/numericConstants.d.ts +1 -1
  24. package/lib/node/constants/numericConstants.d.ts.map +1 -1
  25. package/lib/node/constants/numericConstants.js +1 -1
  26. package/lib/node/decode/user.d.ts.map +1 -1
  27. package/lib/node/decode/user.js +5 -1
  28. package/lib/node/idl/velocity.d.ts +191 -15
  29. package/lib/node/idl/velocity.d.ts.map +1 -1
  30. package/lib/node/idl/velocity.json +192 -16
  31. package/lib/node/orderSubscriber/OrderSubscriber.d.ts +1 -0
  32. package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
  33. package/lib/node/orderSubscriber/OrderSubscriber.js +10 -4
  34. package/lib/node/pyth/pythLazerSubscriber.d.ts.map +1 -1
  35. package/lib/node/pyth/pythLazerSubscriber.js +37 -27
  36. package/lib/node/types.d.ts +6 -0
  37. package/lib/node/types.d.ts.map +1 -1
  38. package/lib/node/user.d.ts +20 -3
  39. package/lib/node/user.d.ts.map +1 -1
  40. package/lib/node/user.js +52 -4
  41. package/lib/node/velocityClient.d.ts +46 -10
  42. package/lib/node/velocityClient.d.ts.map +1 -1
  43. package/lib/node/velocityClient.js +107 -35
  44. package/package.json +7 -3
  45. package/.prettierignore +0 -1
  46. package/CHANGELOG.md +0 -132
  47. package/build-browser.js +0 -58
  48. package/bunfig.toml +0 -3
  49. package/esbuild-shims.js +0 -12
  50. package/scripts/deposit-isolated-positions.ts +0 -110
  51. package/scripts/find-flagged-users.ts +0 -213
  52. package/scripts/grpc-client-test-comparison.ts +0 -372
  53. package/scripts/grpc-multiuser-client-test-comparison.ts +0 -158
  54. package/scripts/postbuild.js +0 -95
  55. package/scripts/single-grpc-client-test.ts +0 -284
  56. package/scripts/withdraw-isolated-positions.ts +0 -174
  57. package/src/accounts/README_WebSocketAccountSubscriberV2.md +0 -95
  58. package/src/accounts/README_WebSocketProgramAccountSubscriberV2.md +0 -135
  59. package/src/accounts/basicUserAccountSubscriber.ts +0 -79
  60. package/src/accounts/basicUserStatsAccountSubscriber.ts +0 -87
  61. package/src/accounts/bulkAccountLoader.ts +0 -358
  62. package/src/accounts/bulkUserStatsSubscription.ts +0 -40
  63. package/src/accounts/bulkUserSubscription.ts +0 -39
  64. package/src/accounts/customizedCadenceBulkAccountLoader.ts +0 -250
  65. package/src/accounts/fetch.ts +0 -200
  66. package/src/accounts/grpcAccountSubscriber.ts +0 -225
  67. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -73
  68. package/src/accounts/grpcMultiAccountSubscriber.ts +0 -566
  69. package/src/accounts/grpcMultiUserAccountSubscriber.ts +0 -328
  70. package/src/accounts/grpcProgramAccountSubscriber.ts +0 -264
  71. package/src/accounts/grpcUserAccountSubscriber.ts +0 -63
  72. package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -65
  73. package/src/accounts/grpcVelocityClientAccountSubscriber.ts +0 -257
  74. package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +0 -941
  75. package/src/accounts/laserProgramAccountSubscriber.ts +0 -266
  76. package/src/accounts/oneShotUserAccountSubscriber.ts +0 -88
  77. package/src/accounts/oneShotUserStatsAccountSubscriber.ts +0 -94
  78. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -223
  79. package/src/accounts/pollingOracleAccountSubscriber.ts +0 -151
  80. package/src/accounts/pollingTokenAccountSubscriber.ts +0 -147
  81. package/src/accounts/pollingUserAccountSubscriber.ts +0 -198
  82. package/src/accounts/pollingUserStatsAccountSubscriber.ts +0 -180
  83. package/src/accounts/pollingVelocityClientAccountSubscriber.ts +0 -774
  84. package/src/accounts/testBulkAccountLoader.ts +0 -59
  85. package/src/accounts/types.ts +0 -428
  86. package/src/accounts/utils.ts +0 -90
  87. package/src/accounts/webSocketAccountSubscriber.ts +0 -304
  88. package/src/accounts/webSocketAccountSubscriberV2.ts +0 -536
  89. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +0 -171
  90. package/src/accounts/webSocketProgramAccountSubscriber.ts +0 -244
  91. package/src/accounts/webSocketProgramAccountSubscriberV2.ts +0 -1048
  92. package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +0 -1042
  93. package/src/accounts/webSocketUserAccountSubscriber.ts +0 -139
  94. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +0 -131
  95. package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +0 -865
  96. package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +0 -897
  97. package/src/accounts/websocketProgramUserAccountSubscriber.ts +0 -127
  98. package/src/addresses/marketAddresses.ts +0 -28
  99. package/src/addresses/pda.ts +0 -620
  100. package/src/adminClient.ts +0 -8136
  101. package/src/assert/assert.ts +0 -5
  102. package/src/auctionSubscriber/auctionSubscriber.ts +0 -86
  103. package/src/auctionSubscriber/auctionSubscriberGrpc.ts +0 -99
  104. package/src/auctionSubscriber/index.ts +0 -9
  105. package/src/auctionSubscriber/types.ts +0 -30
  106. package/src/bankrun/bankrunConnection.ts +0 -630
  107. package/src/blockhashSubscriber/BlockhashSubscriber.ts +0 -160
  108. package/src/blockhashSubscriber/index.ts +0 -6
  109. package/src/blockhashSubscriber/types.ts +0 -13
  110. package/src/clock/clockSubscriber.ts +0 -146
  111. package/src/config.ts +0 -312
  112. package/src/constants/index.ts +0 -9
  113. package/src/constants/numericConstants.ts +0 -194
  114. package/src/constants/perpMarkets.ts +0 -127
  115. package/src/constants/spotMarkets.ts +0 -104
  116. package/src/constants/txConstants.ts +0 -2
  117. package/src/constituentMap/constituentMap.ts +0 -305
  118. package/src/constituentMap/pollingConstituentAccountSubscriber.ts +0 -99
  119. package/src/constituentMap/webSocketConstituentAccountSubscriber.ts +0 -121
  120. package/src/core/VelocityCore.ts +0 -606
  121. package/src/core/index.ts +0 -12
  122. package/src/core/instructions/deposit.ts +0 -64
  123. package/src/core/instructions/fill.ts +0 -51
  124. package/src/core/instructions/funding.ts +0 -33
  125. package/src/core/instructions/liquidation.ts +0 -55
  126. package/src/core/instructions/orders.ts +0 -84
  127. package/src/core/instructions/perpOrders.ts +0 -312
  128. package/src/core/instructions/settlement.ts +0 -40
  129. package/src/core/instructions/trigger.ts +0 -41
  130. package/src/core/instructions/withdraw.ts +0 -65
  131. package/src/core/remainingAccounts.ts +0 -320
  132. package/src/core/signedMsg.ts +0 -109
  133. package/src/decode/customCoder.ts +0 -148
  134. package/src/decode/user.ts +0 -401
  135. package/src/dlob/DLOB.ts +0 -2793
  136. package/src/dlob/DLOBNode.ts +0 -305
  137. package/src/dlob/DLOBSubscriber.ts +0 -269
  138. package/src/dlob/NodeList.ts +0 -244
  139. package/src/dlob/orderBookLevels.ts +0 -695
  140. package/src/dlob/types.ts +0 -37
  141. package/src/events/eventList.ts +0 -114
  142. package/src/events/eventSubscriber.ts +0 -521
  143. package/src/events/eventsServerLogProvider.ts +0 -189
  144. package/src/events/fetchLogs.ts +0 -219
  145. package/src/events/parse.ts +0 -271
  146. package/src/events/pollingLogProvider.ts +0 -113
  147. package/src/events/sort.ts +0 -51
  148. package/src/events/txEventCache.ts +0 -92
  149. package/src/events/types.ts +0 -337
  150. package/src/events/webSocketLogProvider.ts +0 -152
  151. package/src/factory/bigNum.ts +0 -709
  152. package/src/factory/oracleClient.ts +0 -73
  153. package/src/idl/pyth.json +0 -142
  154. package/src/idl/pyth.ts +0 -97
  155. package/src/idl/pyth_solana_receiver.json +0 -628
  156. package/src/idl/token_faucet.json +0 -229
  157. package/src/idl/token_faucet.ts +0 -197
  158. package/src/idl/velocity.json +0 -23974
  159. package/src/idl/velocity.ts +0 -23980
  160. package/src/index.ts +0 -150
  161. package/src/indicative-quotes/indicativeQuotesSender.ts +0 -233
  162. package/src/isomorphic/README.md +0 -19
  163. package/src/isomorphic/anchor.browser.ts +0 -44
  164. package/src/isomorphic/anchor.node.ts +0 -1
  165. package/src/isomorphic/anchor.ts +0 -1
  166. package/src/isomorphic/anchor29.browser.ts +0 -24
  167. package/src/isomorphic/anchor29.node.ts +0 -1
  168. package/src/isomorphic/anchor29.ts +0 -1
  169. package/src/isomorphic/grpc.browser.ts +0 -4
  170. package/src/isomorphic/grpc.node.ts +0 -130
  171. package/src/isomorphic/grpc.ts +0 -1
  172. package/src/jupiter/jupiterClient.ts +0 -502
  173. package/src/keypair.ts +0 -32
  174. package/src/margin/README.md +0 -138
  175. package/src/marginCalculation.ts +0 -407
  176. package/src/marinade/idl/idl.json +0 -1962
  177. package/src/marinade/index.ts +0 -73
  178. package/src/marinade/types.ts +0 -3925
  179. package/src/math/amm.ts +0 -1758
  180. package/src/math/auction.ts +0 -480
  181. package/src/math/bankruptcy.ts +0 -138
  182. package/src/math/builder.ts +0 -130
  183. package/src/math/conversion.ts +0 -45
  184. package/src/math/exchangeStatus.ts +0 -261
  185. package/src/math/funding.ts +0 -498
  186. package/src/math/insurance.ts +0 -171
  187. package/src/math/liquidation.ts +0 -433
  188. package/src/math/margin.ts +0 -327
  189. package/src/math/market.ts +0 -487
  190. package/src/math/oracles.ts +0 -477
  191. package/src/math/orders.ts +0 -500
  192. package/src/math/position.ts +0 -381
  193. package/src/math/repeg.ts +0 -223
  194. package/src/math/spotBalance.ts +0 -996
  195. package/src/math/spotMarket.ts +0 -115
  196. package/src/math/spotPosition.ts +0 -263
  197. package/src/math/state.ts +0 -71
  198. package/src/math/superStake.ts +0 -602
  199. package/src/math/tiers.ts +0 -73
  200. package/src/math/trade.ts +0 -879
  201. package/src/math/utils.ts +0 -183
  202. package/src/memcmp.ts +0 -279
  203. package/src/oracles/oracleClientCache.ts +0 -41
  204. package/src/oracles/oracleId.ts +0 -99
  205. package/src/oracles/prelaunchOracleClient.ts +0 -63
  206. package/src/oracles/pythClient.ts +0 -125
  207. package/src/oracles/pythLazerClient.ts +0 -141
  208. package/src/oracles/quoteAssetOracleClient.ts +0 -43
  209. package/src/oracles/strictOraclePrice.ts +0 -40
  210. package/src/oracles/types.ts +0 -82
  211. package/src/oracles/utils.ts +0 -45
  212. package/src/orderParams.ts +0 -117
  213. package/src/orderSubscriber/OrderSubscriber.ts +0 -378
  214. package/src/orderSubscriber/PollingSubscription.ts +0 -50
  215. package/src/orderSubscriber/WebsocketSubscription.ts +0 -137
  216. package/src/orderSubscriber/grpcSubscription.ts +0 -155
  217. package/src/orderSubscriber/index.ts +0 -7
  218. package/src/orderSubscriber/types.ts +0 -64
  219. package/src/priorityFee/averageOverSlotsStrategy.ts +0 -17
  220. package/src/priorityFee/averageStrategy.ts +0 -13
  221. package/src/priorityFee/ewmaStrategy.ts +0 -51
  222. package/src/priorityFee/heliusPriorityFeeMethod.ts +0 -68
  223. package/src/priorityFee/index.ts +0 -16
  224. package/src/priorityFee/maxOverSlotsStrategy.ts +0 -18
  225. package/src/priorityFee/maxStrategy.ts +0 -8
  226. package/src/priorityFee/priorityFeeSubscriber.ts +0 -328
  227. package/src/priorityFee/priorityFeeSubscriberMap.ts +0 -134
  228. package/src/priorityFee/solanaPriorityFeeMethod.ts +0 -46
  229. package/src/priorityFee/types.ts +0 -82
  230. package/src/priorityFee/velocityPriorityFeeMethod.ts +0 -53
  231. package/src/pyth/constants.ts +0 -9
  232. package/src/pyth/index.ts +0 -15
  233. package/src/pyth/pythLazerSubscriber.ts +0 -365
  234. package/src/pyth/types.ts +0 -4451
  235. package/src/pyth/utils.ts +0 -13
  236. package/src/slot/SlotSubscriber.ts +0 -126
  237. package/src/slot/SlothashSubscriber.ts +0 -163
  238. package/src/swap/UnifiedSwapClient.ts +0 -315
  239. package/src/swift/grpcSignedMsgUserAccountSubscriber.ts +0 -81
  240. package/src/swift/index.ts +0 -10
  241. package/src/swift/signedMsgUserAccountSubscriber.ts +0 -251
  242. package/src/swift/swiftOrderSubscriber.ts +0 -351
  243. package/src/testClient.ts +0 -42
  244. package/src/titan/titanClient.ts +0 -438
  245. package/src/token/index.ts +0 -13
  246. package/src/tokenFaucet.ts +0 -296
  247. package/src/tx/baseTxSender.ts +0 -651
  248. package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +0 -31
  249. package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +0 -105
  250. package/src/tx/blockhashFetcher/types.ts +0 -9
  251. package/src/tx/fastSingleTxSender.ts +0 -200
  252. package/src/tx/forwardOnlyTxSender.ts +0 -193
  253. package/src/tx/priorityFeeCalculator.ts +0 -117
  254. package/src/tx/reportTransactionError.ts +0 -176
  255. package/src/tx/retryTxSender.ts +0 -177
  256. package/src/tx/txHandler.ts +0 -1009
  257. package/src/tx/txParamProcessor.ts +0 -225
  258. package/src/tx/types.ts +0 -117
  259. package/src/tx/utils.ts +0 -133
  260. package/src/tx/whileValidTxSender.ts +0 -377
  261. package/src/types.ts +0 -2575
  262. package/src/user.ts +0 -5316
  263. package/src/userConfig.ts +0 -38
  264. package/src/userMap/PollingSubscription.ts +0 -61
  265. package/src/userMap/WebsocketSubscription.ts +0 -93
  266. package/src/userMap/grpcSubscription.ts +0 -93
  267. package/src/userMap/referrerMap.ts +0 -360
  268. package/src/userMap/revenueShareEscrowMap.ts +0 -342
  269. package/src/userMap/userMap.ts +0 -784
  270. package/src/userMap/userMapConfig.ts +0 -82
  271. package/src/userMap/userStatsMap.ts +0 -393
  272. package/src/userName.ts +0 -37
  273. package/src/userStats.ts +0 -159
  274. package/src/userStatsConfig.ts +0 -35
  275. package/src/util/TransactionConfirmationManager.ts +0 -333
  276. package/src/util/chainClock.ts +0 -65
  277. package/src/util/computeUnits.ts +0 -101
  278. package/src/util/digest.ts +0 -33
  279. package/src/util/ed25519Utils.ts +0 -95
  280. package/src/util/promiseTimeout.ts +0 -23
  281. package/src/velocityClient.ts +0 -14802
  282. package/src/velocityClientConfig.ts +0 -119
  283. package/src/wallet.ts +0 -91
  284. package/tests/VelocityCore/builder_escrow.test.ts +0 -121
  285. package/tests/VelocityCore/decode.test.ts +0 -16
  286. package/tests/VelocityCore/fill_trigger.test.ts +0 -73
  287. package/tests/VelocityCore/instructions.test.ts +0 -46
  288. package/tests/VelocityCore/pdas.test.ts +0 -30
  289. package/tests/VelocityCore/perp_orders.test.ts +0 -205
  290. package/tests/VelocityCore/remainingAccounts.test.ts +0 -72
  291. package/tests/VelocityCore/settlement_liquidation.test.ts +0 -69
  292. package/tests/accounts/customizedCadenceBulkAccountLoader.test.ts +0 -211
  293. package/tests/amm/test.ts +0 -2402
  294. package/tests/auctions/test.ts +0 -81
  295. package/tests/bn/test.ts +0 -355
  296. package/tests/builder/builderFee.test.ts +0 -42
  297. package/tests/ci/verifyConstants.ts +0 -393
  298. package/tests/decode/test.ts +0 -262
  299. package/tests/decode/userAccountBufferStrings.ts +0 -102
  300. package/tests/dlob/helpers.ts +0 -748
  301. package/tests/dlob/test.ts +0 -6969
  302. package/tests/dlob/tickSizeStandardization.ts +0 -545
  303. package/tests/events/parseLogsForCuUsage.ts +0 -139
  304. package/tests/exchangeStatus/test.ts +0 -45
  305. package/tests/insurance/test.ts +0 -40
  306. package/tests/liquidation/test.ts +0 -125
  307. package/tests/oracles/mmOracleGate.test.ts +0 -379
  308. package/tests/oracles/pythPegSnap.test.ts +0 -76
  309. package/tests/sdkParity/enumParity.test.ts +0 -84
  310. package/tests/sdkParity/marginCategoryFill.test.ts +0 -143
  311. package/tests/sdkParity/memcmpOffsets.test.ts +0 -139
  312. package/tests/spot/test.ts +0 -281
  313. package/tests/tx/TransactionConfirmationManager.test.ts +0 -312
  314. package/tests/tx/cachedBlockhashFetcher.test.ts +0 -96
  315. package/tests/tx/priorityFeeCalculator.ts +0 -77
  316. package/tests/tx/priorityFeeStrategy.ts +0 -95
  317. package/tests/user/bankruptcy.ts +0 -165
  318. package/tests/user/feeAndWithdrawLimits.ts +0 -284
  319. package/tests/user/getMarginCalculation.ts +0 -586
  320. package/tests/user/helpers.ts +0 -184
  321. package/tests/user/liquidations.ts +0 -129
  322. package/tests/user/marginCalculations.test.ts +0 -321
  323. package/tests/user/test.ts +0 -833
  324. package/tsconfig.browser.json +0 -18
  325. 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
- }