@d8x/perpetuals-sdk 2.6.23 → 2.7.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 (263) hide show
  1. package/dist/cjs/config/defaultConfig.json +2 -2
  2. package/dist/cjs/constants.js.map +1 -1
  3. package/dist/cjs/d8XMath.d.ts +40 -29
  4. package/dist/cjs/d8XMath.js +244 -151
  5. package/dist/cjs/d8XMath.js.map +1 -1
  6. package/dist/cjs/liquidatorTool.d.ts +1 -1
  7. package/dist/cjs/liquidatorTool.js +9 -9
  8. package/dist/cjs/liquidatorTool.js.map +1 -1
  9. package/dist/cjs/main.d.ts +1 -0
  10. package/dist/cjs/main.js +15 -0
  11. package/dist/cjs/main.js.map +1 -0
  12. package/dist/cjs/marketData.d.ts +7 -11
  13. package/dist/cjs/marketData.js +31 -20
  14. package/dist/cjs/marketData.js.map +1 -1
  15. package/dist/cjs/perpetualDataHandler.d.ts +12 -12
  16. package/dist/cjs/perpetualDataHandler.js +13 -14
  17. package/dist/cjs/perpetualDataHandler.js.map +1 -1
  18. package/dist/cjs/polyMktsPxFeed.js +2 -2
  19. package/dist/cjs/polyMktsPxFeed.js.map +1 -1
  20. package/dist/cjs/priceFeeds.d.ts +1 -0
  21. package/dist/cjs/priceFeeds.js +19 -3
  22. package/dist/cjs/priceFeeds.js.map +1 -1
  23. package/dist/cjs/version.d.ts +1 -1
  24. package/dist/cjs/version.js +1 -1
  25. package/dist/esm/config/defaultConfig.json +2 -2
  26. package/dist/esm/constants.js.map +1 -1
  27. package/dist/esm/d8XMath.d.ts +40 -29
  28. package/dist/esm/d8XMath.js +241 -150
  29. package/dist/esm/d8XMath.js.map +1 -1
  30. package/dist/esm/liquidatorTool.d.ts +1 -1
  31. package/dist/esm/liquidatorTool.js +10 -10
  32. package/dist/esm/liquidatorTool.js.map +1 -1
  33. package/dist/esm/main.d.ts +1 -0
  34. package/dist/esm/main.js +13 -0
  35. package/dist/esm/main.js.map +1 -0
  36. package/dist/esm/main2.d.ts +1 -0
  37. package/dist/esm/main2.js +18 -0
  38. package/dist/esm/main2.js.map +1 -0
  39. package/dist/esm/marketData.d.ts +7 -11
  40. package/dist/esm/marketData.js +32 -21
  41. package/dist/esm/marketData.js.map +1 -1
  42. package/dist/esm/perpetualDataHandler.d.ts +12 -12
  43. package/dist/esm/perpetualDataHandler.js +13 -14
  44. package/dist/esm/perpetualDataHandler.js.map +1 -1
  45. package/dist/esm/polyMktsPxFeed.js +2 -2
  46. package/dist/esm/polyMktsPxFeed.js.map +1 -1
  47. package/dist/esm/priceFeeds.d.ts +1 -0
  48. package/dist/esm/priceFeeds.js +19 -3
  49. package/dist/esm/priceFeeds.js.map +1 -1
  50. package/dist/esm/version.d.ts +1 -1
  51. package/dist/esm/version.js +1 -1
  52. package/doc/d8x-perpetuals-sdk.md +109 -81
  53. package/doc/marketData.md +2 -10
  54. package/package.json +5 -2
  55. package/src/config/defaultConfig.json +2 -2
  56. package/src/constants.ts +0 -1
  57. package/src/d8XMath.ts +268 -167
  58. package/src/liquidatorTool.ts +16 -10
  59. package/src/marketData.ts +62 -35
  60. package/src/perpetualDataHandler.ts +28 -34
  61. package/src/polyMktsPxFeed.ts +6 -7
  62. package/src/priceFeeds.ts +20 -4
  63. package/src/version.ts +1 -1
  64. package/dist/cjs/abi/AMMPerpLogic.json +0 -580
  65. package/dist/cjs/abi/BeaconProxy.json +0 -71
  66. package/dist/cjs/abi/IPerpetualManager copy.json +0 -5599
  67. package/dist/cjs/abi/IPerpetualMarginViewLogic.json +0 -286
  68. package/dist/cjs/abi/Maintainer.json +0 -774
  69. package/dist/cjs/abi/MockToken.json +0 -347
  70. package/dist/cjs/abi/MockUSD.json +0 -413
  71. package/dist/cjs/abi/UUPSUpgradeable.json +0 -104
  72. package/dist/cjs/abi/WeETH.json +0 -310
  73. package/dist/cjs/abi-zkevm/IPerpetualManager.json +0 -5366
  74. package/dist/cjs/abi-zkevm/LimitOrderBook.json +0 -910
  75. package/dist/cjs/abi-zkevm/LimitOrderBookFactory.json +0 -236
  76. package/dist/cjs/contracts/AMMPerpLogic.d.ts +0 -303
  77. package/dist/cjs/contracts/AMMPerpLogic.js +0 -3
  78. package/dist/cjs/contracts/AMMPerpLogic.js.map +0 -1
  79. package/dist/cjs/contracts/BeaconProxy.d.ts +0 -63
  80. package/dist/cjs/contracts/BeaconProxy.js +0 -3
  81. package/dist/cjs/contracts/BeaconProxy.js.map +0 -1
  82. package/dist/cjs/contracts/IPerpetualManagerCopy.d.ts +0 -3223
  83. package/dist/cjs/contracts/IPerpetualManagerCopy.js +0 -3
  84. package/dist/cjs/contracts/IPerpetualManagerCopy.js.map +0 -1
  85. package/dist/cjs/contracts/IPerpetualMarginViewLogic.d.ts +0 -183
  86. package/dist/cjs/contracts/IPerpetualMarginViewLogic.js +0 -3
  87. package/dist/cjs/contracts/IPerpetualMarginViewLogic.js.map +0 -1
  88. package/dist/cjs/contracts/Maintainer.d.ts +0 -799
  89. package/dist/cjs/contracts/Maintainer.js +0 -3
  90. package/dist/cjs/contracts/Maintainer.js.map +0 -1
  91. package/dist/cjs/contracts/MockToken.d.ts +0 -263
  92. package/dist/cjs/contracts/MockToken.js +0 -3
  93. package/dist/cjs/contracts/MockToken.js.map +0 -1
  94. package/dist/cjs/contracts/MockUSD.d.ts +0 -186
  95. package/dist/cjs/contracts/MockUSD.js +0 -3
  96. package/dist/cjs/contracts/MockUSD.js.map +0 -1
  97. package/dist/cjs/contracts/UUPSUpgradeable.d.ts +0 -118
  98. package/dist/cjs/contracts/UUPSUpgradeable.js +0 -3
  99. package/dist/cjs/contracts/UUPSUpgradeable.js.map +0 -1
  100. package/dist/cjs/contracts/WeETH.d.ts +0 -503
  101. package/dist/cjs/contracts/WeETH.js +0 -3
  102. package/dist/cjs/contracts/WeETH.js.map +0 -1
  103. package/dist/cjs/contracts/factories/AMMPerpLogic__factory.d.ts +0 -452
  104. package/dist/cjs/contracts/factories/AMMPerpLogic__factory.js +0 -598
  105. package/dist/cjs/contracts/factories/AMMPerpLogic__factory.js.map +0 -1
  106. package/dist/cjs/contracts/factories/BeaconProxy__factory.d.ts +0 -61
  107. package/dist/cjs/contracts/factories/BeaconProxy__factory.js +0 -89
  108. package/dist/cjs/contracts/factories/BeaconProxy__factory.js.map +0 -1
  109. package/dist/cjs/contracts/factories/IPerpetualManagerCopy__factory.d.ts +0 -4358
  110. package/dist/cjs/contracts/factories/IPerpetualManagerCopy__factory.js +0 -5617
  111. package/dist/cjs/contracts/factories/IPerpetualManagerCopy__factory.js.map +0 -1
  112. package/dist/cjs/contracts/factories/IPerpetualMarginViewLogic__factory.d.ts +0 -221
  113. package/dist/cjs/contracts/factories/IPerpetualMarginViewLogic__factory.js +0 -304
  114. package/dist/cjs/contracts/factories/IPerpetualMarginViewLogic__factory.js.map +0 -1
  115. package/dist/cjs/contracts/factories/Maintainer__factory.d.ts +0 -609
  116. package/dist/cjs/contracts/factories/Maintainer__factory.js +0 -792
  117. package/dist/cjs/contracts/factories/Maintainer__factory.js.map +0 -1
  118. package/dist/cjs/contracts/factories/MockToken__factory.d.ts +0 -273
  119. package/dist/cjs/contracts/factories/MockToken__factory.js +0 -365
  120. package/dist/cjs/contracts/factories/MockToken__factory.js.map +0 -1
  121. package/dist/cjs/contracts/factories/MockUSD__factory.d.ts +0 -320
  122. package/dist/cjs/contracts/factories/MockUSD__factory.js +0 -431
  123. package/dist/cjs/contracts/factories/MockUSD__factory.js.map +0 -1
  124. package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.d.ts +0 -87
  125. package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.js +0 -122
  126. package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.js.map +0 -1
  127. package/dist/cjs/contracts/factories/WeETH__factory.d.ts +0 -545
  128. package/dist/cjs/contracts/factories/WeETH__factory.js +0 -721
  129. package/dist/cjs/contracts/factories/WeETH__factory.js.map +0 -1
  130. package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.d.ts +0 -4136
  131. package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.js +0 -5324
  132. package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.js.map +0 -1
  133. package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.d.ts +0 -189
  134. package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.js +0 -254
  135. package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.js.map +0 -1
  136. package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.d.ts +0 -715
  137. package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.js +0 -928
  138. package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.js.map +0 -1
  139. package/dist/cjs/contracts/factories/lean0/ShareToken__factory.d.ts +0 -344
  140. package/dist/cjs/contracts/factories/lean0/ShareToken__factory.js +0 -456
  141. package/dist/cjs/contracts/factories/lean0/ShareToken__factory.js.map +0 -1
  142. package/dist/cjs/contracts/factories/lean0/index.d.ts +0 -4
  143. package/dist/cjs/contracts/factories/lean0/index.js +0 -15
  144. package/dist/cjs/contracts/factories/lean0/index.js.map +0 -1
  145. package/dist/cjs/contracts/lean0/IPerpetualManager.d.ts +0 -2821
  146. package/dist/cjs/contracts/lean0/IPerpetualManager.js +0 -3
  147. package/dist/cjs/contracts/lean0/IPerpetualManager.js.map +0 -1
  148. package/dist/cjs/contracts/lean0/LimitOrderBook.d.ts +0 -533
  149. package/dist/cjs/contracts/lean0/LimitOrderBook.js +0 -3
  150. package/dist/cjs/contracts/lean0/LimitOrderBook.js.map +0 -1
  151. package/dist/cjs/contracts/lean0/LimitOrderBookFactory.d.ts +0 -210
  152. package/dist/cjs/contracts/lean0/LimitOrderBookFactory.js +0 -3
  153. package/dist/cjs/contracts/lean0/LimitOrderBookFactory.js.map +0 -1
  154. package/dist/cjs/contracts/lean0/ShareToken.d.ts +0 -320
  155. package/dist/cjs/contracts/lean0/ShareToken.js +0 -3
  156. package/dist/cjs/contracts/lean0/ShareToken.js.map +0 -1
  157. package/dist/cjs/contracts/lean0/index.d.ts +0 -4
  158. package/dist/cjs/contracts/lean0/index.js +0 -3
  159. package/dist/cjs/contracts/lean0/index.js.map +0 -1
  160. package/dist/esm/abi/AMMPerpLogic.json +0 -580
  161. package/dist/esm/abi/BeaconProxy.json +0 -71
  162. package/dist/esm/abi/IPerpetualManager copy.json +0 -5599
  163. package/dist/esm/abi/IPerpetualMarginViewLogic.json +0 -286
  164. package/dist/esm/abi/Maintainer.json +0 -774
  165. package/dist/esm/abi/MockToken.json +0 -347
  166. package/dist/esm/abi/MockUSD.json +0 -413
  167. package/dist/esm/abi/UUPSUpgradeable.json +0 -104
  168. package/dist/esm/abi/WeETH.json +0 -310
  169. package/dist/esm/abi/lean0/IPerpetualManager.json +0 -5306
  170. package/dist/esm/abi/lean0/LimitOrderBook.json +0 -910
  171. package/dist/esm/abi/lean0/LimitOrderBookFactory.json +0 -236
  172. package/dist/esm/abi/lean0/ShareToken.json +0 -438
  173. package/dist/esm/abi-zkevm/IPerpetualManager.json +0 -5366
  174. package/dist/esm/abi-zkevm/LimitOrderBook.json +0 -910
  175. package/dist/esm/abi-zkevm/LimitOrderBookFactory.json +0 -236
  176. package/dist/esm/contracts/AMMPerpLogic.d.ts +0 -303
  177. package/dist/esm/contracts/AMMPerpLogic.js +0 -2
  178. package/dist/esm/contracts/AMMPerpLogic.js.map +0 -1
  179. package/dist/esm/contracts/BeaconProxy.d.ts +0 -63
  180. package/dist/esm/contracts/BeaconProxy.js +0 -2
  181. package/dist/esm/contracts/BeaconProxy.js.map +0 -1
  182. package/dist/esm/contracts/IPerpetualManagerCopy.d.ts +0 -3223
  183. package/dist/esm/contracts/IPerpetualManagerCopy.js +0 -2
  184. package/dist/esm/contracts/IPerpetualManagerCopy.js.map +0 -1
  185. package/dist/esm/contracts/IPerpetualMarginViewLogic.d.ts +0 -183
  186. package/dist/esm/contracts/IPerpetualMarginViewLogic.js +0 -2
  187. package/dist/esm/contracts/IPerpetualMarginViewLogic.js.map +0 -1
  188. package/dist/esm/contracts/Maintainer.d.ts +0 -799
  189. package/dist/esm/contracts/Maintainer.js +0 -2
  190. package/dist/esm/contracts/Maintainer.js.map +0 -1
  191. package/dist/esm/contracts/MockToken.d.ts +0 -263
  192. package/dist/esm/contracts/MockToken.js +0 -2
  193. package/dist/esm/contracts/MockToken.js.map +0 -1
  194. package/dist/esm/contracts/MockUSD.d.ts +0 -186
  195. package/dist/esm/contracts/MockUSD.js +0 -2
  196. package/dist/esm/contracts/MockUSD.js.map +0 -1
  197. package/dist/esm/contracts/UUPSUpgradeable.d.ts +0 -118
  198. package/dist/esm/contracts/UUPSUpgradeable.js +0 -2
  199. package/dist/esm/contracts/UUPSUpgradeable.js.map +0 -1
  200. package/dist/esm/contracts/WeETH.d.ts +0 -503
  201. package/dist/esm/contracts/WeETH.js +0 -2
  202. package/dist/esm/contracts/WeETH.js.map +0 -1
  203. package/dist/esm/contracts/factories/AMMPerpLogic__factory.d.ts +0 -452
  204. package/dist/esm/contracts/factories/AMMPerpLogic__factory.js +0 -594
  205. package/dist/esm/contracts/factories/AMMPerpLogic__factory.js.map +0 -1
  206. package/dist/esm/contracts/factories/BeaconProxy__factory.d.ts +0 -61
  207. package/dist/esm/contracts/factories/BeaconProxy__factory.js +0 -85
  208. package/dist/esm/contracts/factories/BeaconProxy__factory.js.map +0 -1
  209. package/dist/esm/contracts/factories/IPerpetualManagerCopy__factory.d.ts +0 -4358
  210. package/dist/esm/contracts/factories/IPerpetualManagerCopy__factory.js +0 -5613
  211. package/dist/esm/contracts/factories/IPerpetualManagerCopy__factory.js.map +0 -1
  212. package/dist/esm/contracts/factories/IPerpetualMarginViewLogic__factory.d.ts +0 -221
  213. package/dist/esm/contracts/factories/IPerpetualMarginViewLogic__factory.js +0 -300
  214. package/dist/esm/contracts/factories/IPerpetualMarginViewLogic__factory.js.map +0 -1
  215. package/dist/esm/contracts/factories/Maintainer__factory.d.ts +0 -609
  216. package/dist/esm/contracts/factories/Maintainer__factory.js +0 -788
  217. package/dist/esm/contracts/factories/Maintainer__factory.js.map +0 -1
  218. package/dist/esm/contracts/factories/MockToken__factory.d.ts +0 -273
  219. package/dist/esm/contracts/factories/MockToken__factory.js +0 -361
  220. package/dist/esm/contracts/factories/MockToken__factory.js.map +0 -1
  221. package/dist/esm/contracts/factories/MockUSD__factory.d.ts +0 -320
  222. package/dist/esm/contracts/factories/MockUSD__factory.js +0 -427
  223. package/dist/esm/contracts/factories/MockUSD__factory.js.map +0 -1
  224. package/dist/esm/contracts/factories/UUPSUpgradeable__factory.d.ts +0 -87
  225. package/dist/esm/contracts/factories/UUPSUpgradeable__factory.js +0 -118
  226. package/dist/esm/contracts/factories/UUPSUpgradeable__factory.js.map +0 -1
  227. package/dist/esm/contracts/factories/WeETH__factory.d.ts +0 -545
  228. package/dist/esm/contracts/factories/WeETH__factory.js +0 -717
  229. package/dist/esm/contracts/factories/WeETH__factory.js.map +0 -1
  230. package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.d.ts +0 -4136
  231. package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.js +0 -5320
  232. package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.js.map +0 -1
  233. package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.d.ts +0 -189
  234. package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.js +0 -250
  235. package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.js.map +0 -1
  236. package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.d.ts +0 -715
  237. package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.js +0 -924
  238. package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.js.map +0 -1
  239. package/dist/esm/contracts/factories/lean0/ShareToken__factory.d.ts +0 -344
  240. package/dist/esm/contracts/factories/lean0/ShareToken__factory.js +0 -452
  241. package/dist/esm/contracts/factories/lean0/ShareToken__factory.js.map +0 -1
  242. package/dist/esm/contracts/factories/lean0/index.d.ts +0 -4
  243. package/dist/esm/contracts/factories/lean0/index.js +0 -8
  244. package/dist/esm/contracts/factories/lean0/index.js.map +0 -1
  245. package/dist/esm/contracts/lean0/IPerpetualManager.d.ts +0 -2821
  246. package/dist/esm/contracts/lean0/IPerpetualManager.js +0 -2
  247. package/dist/esm/contracts/lean0/IPerpetualManager.js.map +0 -1
  248. package/dist/esm/contracts/lean0/LimitOrderBook.d.ts +0 -533
  249. package/dist/esm/contracts/lean0/LimitOrderBook.js +0 -2
  250. package/dist/esm/contracts/lean0/LimitOrderBook.js.map +0 -1
  251. package/dist/esm/contracts/lean0/LimitOrderBookFactory.d.ts +0 -210
  252. package/dist/esm/contracts/lean0/LimitOrderBookFactory.js +0 -2
  253. package/dist/esm/contracts/lean0/LimitOrderBookFactory.js.map +0 -1
  254. package/dist/esm/contracts/lean0/ShareToken.d.ts +0 -320
  255. package/dist/esm/contracts/lean0/ShareToken.js +0 -2
  256. package/dist/esm/contracts/lean0/ShareToken.js.map +0 -1
  257. package/dist/esm/contracts/lean0/index.d.ts +0 -4
  258. package/dist/esm/contracts/lean0/index.js +0 -2
  259. package/dist/esm/contracts/lean0/index.js.map +0 -1
  260. package/src/contracts/IPerpetualMarginViewLogic.ts +0 -347
  261. package/src/contracts/MockUSD.ts +0 -378
  262. package/src/contracts/factories/IPerpetualMarginViewLogic__factory.ts +0 -313
  263. package/src/contracts/factories/MockUSD__factory.ts +0 -430
package/src/d8XMath.ts CHANGED
@@ -410,7 +410,7 @@ export function getNewPositionLeverage(
410
410
  * @param {number} price - price to trade amount 'tradeAmnt'
411
411
  * @param {number} S3 - collateral to quote conversion (=S2 if base-collateral, =1 if quote collateral, = index S3 if quanto)
412
412
  * @param {number} S2Mark - mark price
413
- * @param {boolean} isPredMkt - true if prediction market
413
+ * @param {number} cmin - Absolute minimum margin per contract, only for pred markets
414
414
  * @returns {number} Amount to be deposited to have the given leverage when trading into position pos before fees
415
415
  */
416
416
  export function getDepositAmountForLvgTrade(
@@ -421,29 +421,112 @@ export function getDepositAmountForLvgTrade(
421
421
  price: number,
422
422
  S3: number,
423
423
  S2Mark: number,
424
- isPredMkt: boolean
424
+ cmin: number | undefined
425
425
  ) {
426
- let pnl = (tradeAmnt * (S2Mark - price)) / S3;
427
- let S2MarkBefore = S2Mark;
428
- if (isPredMkt) {
429
- // adjust mark price to 'probability'
430
- S2Mark = S2Mark - 1;
431
- S2MarkBefore = S2Mark;
432
- if (pos0 < 0) {
433
- S2MarkBefore = 1 - S2Mark;
434
- }
435
- if (pos0 + tradeAmnt < 0) {
436
- S2Mark = 1 - S2Mark;
426
+ if (cmin && cmin > 0) {
427
+ // TODO: c0?
428
+ if (b0 != 0) {
429
+ console.log("b0 != 0");
437
430
  }
431
+ return getDepositAmountForPredMktLvgTrade(pos0, b0, 0, tradeAmnt, targetLvg, price - 1, S3, S2Mark - 1, cmin);
438
432
  }
433
+ let pnl = (tradeAmnt * (S2Mark - price)) / S3;
439
434
  if (targetLvg == 0) {
440
435
  // use current leverage
441
- targetLvg = (Math.abs(pos0) * S2MarkBefore) / S3 / b0;
436
+ targetLvg = (Math.abs(pos0) * S2Mark) / S3 / b0;
442
437
  }
443
438
  let b = (Math.abs(pos0 + tradeAmnt) * S2Mark) / S3 / targetLvg;
444
439
  return -(b0 + pnl - b);
445
440
  }
446
441
 
442
+ /**
443
+ * Determine amount to be deposited into margin account so that the given leverage
444
+ * is obtained when opening a prediction market position
445
+ * Does NOT include fees, but accounts for a possible non-zero current position
446
+ * Smart contract equivalent: getDepositAmountForPredMktLvgPosition
447
+ * @param {number} pos0 - current position
448
+ * @param {number} b0 - current balance
449
+ * @param {number} c0 - current available cash
450
+ * @param {number} tradeAmnt - amount to trade
451
+ * @param {number} targetLvg - target leverage
452
+ * @param {number} prob - prob to trade amount 'tradeAmnt'
453
+ * @param {number} S3 - collateral to quote conversion (=S2 if base-collateral, =1 if quote collateral, = index S3 if quanto)
454
+ * @param {number} markProb - mark prob
455
+ * @param {number} imr - minimum absolute margin per contract (fInitialMarginRate)
456
+ * @returns {number} Amount to be deposited to have the given leverage when trading into position pos before fees
457
+ */
458
+ export function getDepositAmountForPredMktLvgTrade(
459
+ pos0: number,
460
+ b0: number,
461
+ c0: number,
462
+ tradeAmnt: number,
463
+ targetLvg: number,
464
+ prob: number,
465
+ S3: number,
466
+ markProb: number,
467
+ imr: number
468
+ ) {
469
+ /**
470
+ * Smart contract implementation:
471
+ // find smallest x such that:
472
+ // bal * s3 >= pos value / lvg
473
+ // where:
474
+ // pos value / lvg = |pos| * R(pm, sign(pos)) * margin rate
475
+ // pos = pos0 + k
476
+ // cash = cash0 + x
477
+ // ell = ell0 + px * k
478
+ // bal * s3 = cash * s3 + pos * sm - ell
479
+ // = bal0 * s3 + x * s3 + k * (sm - px)
480
+
481
+ // subject to:
482
+ // x >= 0
483
+ // cash * s3 >= |pos| * min(cmin, prob(sign(pos)))
484
+ // k * (sm - px) <= 0 a.s.
485
+ // (positive pnl does not contribute, i.e. ignore px better than mark)
486
+
487
+ // solution:
488
+ // bal0 * s3 + x * s3 >= pos value / lvg + (k * (px - sm))_+ = v * s3
489
+ // -->
490
+ // x >= v + (cash0 - bal0)_+ - cash0 = v - min(bal0, cash0)
491
+ // = pos value / lvg/ s3 + (k * (px - sm))_+ / s3 - min (bal0, cash0)
492
+ // = A + B - C
493
+ // x >= |pos| * min(cmin, prob(sign(pos))) / s3 - cash0
494
+ // x >= 0
495
+
496
+ // init x = A = pos value / lvg / s3
497
+ int128 fNewPos = _fPosition0.add(_fTradeAmount);
498
+ int128 v = (
499
+ fNewPos > 0 ? fNewPos.mul(_fMarkProb) : fNewPos.neg().mul(ONE_64x64.sub(_fMarkProb))
500
+ ).mul(_fMarginRate).div(_fS3);
501
+ // + B = max(0,k * (px - sm)) / s3
502
+ {
503
+ int128 fPnL = _fTradeAmount.mul(_fMarkProb.sub(_fTradeProb));
504
+ if (fPnL < 0) {
505
+ v = v.sub(fPnL.div(_fS3)); // pnl < 0 -> increase v
506
+ }
507
+ }
508
+ // - C = - min(bal0, cash0) = - Equity
509
+ {
510
+ int128 equity = _fCash0CC < _fBalance0 ? _fCash0CC : _fBalance0;
511
+ v = v.sub(equity); // equity can be used / must be covered if negative
512
+ }
513
+ return v > 0 ? v : int128(0);
514
+ */
515
+
516
+ const newPos = pos0 + tradeAmnt;
517
+ const posProb = newPos > 0 ? markProb : 1 - markProb; // R(pm, sign(new pos))
518
+ const maxLvg = pmMaxLeverage(newPos, markProb, imr);
519
+ targetLvg = targetLvg > maxLvg ? maxLvg : targetLvg;
520
+ const posValue = (Math.abs(newPos) * posProb) / S3;
521
+ const tradeLoss = Math.max(0, tradeAmnt * (prob - markProb)) / S3;
522
+ const curEquity = Math.min(c0, b0);
523
+ return Math.max(posValue / targetLvg + tradeLoss - curEquity, 0);
524
+ }
525
+
526
+ function pmMaxLeverage(posSign: number, markProb: number, minMarginPerCtrct: number) {
527
+ return Math.round(100 * (posSign > 0 ? markProb / minMarginPerCtrct : (1 - markProb) / minMarginPerCtrct)) / 100;
528
+ }
529
+
447
530
  /**
448
531
  * Convert a perpetual price to probability (predtictive markets)
449
532
  * @param px Perpetual price
@@ -459,7 +542,7 @@ export function priceToProb(px: number) {
459
542
  * @returns Perpetual price
460
543
  */
461
544
  export function probToPrice(prob: number) {
462
- return 1 + prob;
545
+ return Math.max(1, Math.min(2, 1 + prob));
463
546
  }
464
547
 
465
548
  // shannon entropy
@@ -473,118 +556,62 @@ export function entropy(prob: number) {
473
556
  /**
474
557
  * Maintenance margin requirement for prediction markets
475
558
  * @param pos signed position
559
+ * @param lockedInQC locked in value
476
560
  * @param s2 mark price
477
561
  * @param s3 collateral to quote conversion
478
562
  * @param m base margin rate
479
563
  * @returns required margin balance
480
564
  */
481
- function pmMarginThresh(pos: number, s2: number, s3: number, m: number | undefined = 0.18) {
482
- let p = s2 - 1;
483
- if (pos < 0) {
484
- p = 1 - p;
485
- }
486
- const h = entropy(p);
487
- const tau = m + (0.4 - m) * h;
488
- return (Math.abs(pos) * p * tau) / s3;
565
+ function pmMarginThresh(pos: number, lockedInQC: number, s2: number, s3: number, m: number): number {
566
+ return (pmMaintenanceMarginRate(pos, lockedInQC, s2, m) * Math.abs(pos)) / s3;
489
567
  }
490
568
 
491
569
  /**
492
570
  * Maintenance margin rate for prediction markets.
493
- * @param posSign sign of position in base currency (can be signed position or -1, 1)
571
+ * @param position signed position in base currency
572
+ * @param lockedInQC locked in value, p or 1-p times number of contracts
494
573
  * @param sm mark-price (=1+p)
495
- * @param m max margin rate from fInitialMarginRate
496
- * @returns margin rate to be applied (Math.abs(pos) * p * tau) / s3;
497
- */
498
- export function pmMaintenanceMarginRate(posSign: number, sm: number, m: number | undefined = 0.18): number {
499
- let p = sm - 1;
500
- if (posSign < 0) {
501
- p = 1 - p;
574
+ * @param m absolute maintenance buffer per contract (mu_m, fMaintenanceMarginRate)
575
+ * @returns {number} The margin rate to be applied: (Math.abs(pos) * p * tau) / s3
576
+ */ pmExchangeFee;
577
+ export function pmMaintenanceMarginRate(position: number, lockedInQC: number, sm: number, m: number): number {
578
+ let pm = sm - 1;
579
+ let entryP = position == 0 ? pm : Math.abs(lockedInQC / position) - 1;
580
+ if (position < 0) {
581
+ pm = 1 - pm;
582
+ entryP = 1 - entryP;
583
+ }
584
+ const L = Math.max(entryP - pm, 0);
585
+ if (position == 0) {
586
+ return Math.min(m + L, entryP) / pm;
587
+ } else {
588
+ const balAtLiq = Math.min(m + L, entryP) * Math.abs(position) + (position * sm - lockedInQC);
589
+ return balAtLiq / pm / Math.abs(position);
502
590
  }
503
- const h = entropy(p);
504
- return m + (0.4 - m) * h;
505
591
  }
506
592
 
507
593
  /**
508
- * Maintenance margin rate for prediction markets.
594
+ * Initial margin rate for prediction markets.
509
595
  * @param posSign sign of position in base currency (can be signed position or -1, 1)
596
+ * @param s0 trade price
510
597
  * @param sm mark-price (=1+p)
511
- * @param m max margin rate from fMaintenanceMarginRate
512
- * @returns margin rate to be applied (Math.abs(pos) * p * tau) / s3;
598
+ * @param cmin Absolute min margin saved as `fInitialMarginRate`
599
+ * @returns {number} The margin rate to be applied: `(Math.abs(pos) * p * tau) / s3`
513
600
  */
514
- export function pmInitialMarginRate(posSign: number, sm: number, m: number | undefined = 0.2): number {
515
- let p = sm - 1;
601
+ export function pmInitialMarginRate(posSign: number, s0: number, sm: number, cmin: number): number {
602
+ let pm = sm - 1;
603
+ let p0 = s0 - 1;
516
604
  if (posSign < 0) {
517
- p = 1 - p;
605
+ pm = 1 - pm; // R(p_mark, sign(pos))
606
+ p0 = 1 - p0; // R(p_entry, sign(pos))
518
607
  }
519
- const h = entropy(p);
520
- return m + (0.5 - m) * h;
521
- }
522
-
523
- /**
524
- * Calculate the expected loss for a prediction market trade used for
525
- * prediction market fees
526
- * @param p probability derived from mark price (long)
527
- * @param m maximal maintenance rate from which we defer the actual maintenance margin rate
528
- * @param totLong total long in base currency
529
- * @param totShort total short
530
- * @param tradeAmt signed trade amount, can be zero
531
- * @param tradeMgnRate margin rate of the trader
532
- * @returns expected loss in dollars
533
- */
534
- export function expectedLoss(
535
- p: number,
536
- m: number,
537
- totLong: number,
538
- totShort: number,
539
- tradeAmt: number,
540
- tradeMgnRate: number
541
- ): number {
542
- // maintenance margin rate
543
- m = (0.4 - m) * entropy(p) + m;
544
- let dlm = 0;
545
- let dl = 0;
546
- let dsm = 0;
547
- let ds = 0;
548
- if (tradeAmt > 0) {
549
- dlm = p * tradeAmt * tradeMgnRate;
550
- dl = tradeAmt;
551
- } else if (tradeAmt < 0) {
552
- dsm = (1 - p) * Math.abs(tradeAmt) * tradeMgnRate;
553
- ds = Math.abs(tradeAmt);
554
- }
555
- const a = dl + totLong - m * totShort - dsm;
556
- const b = ds + totShort - m * totLong - dlm;
557
- return p * (1 - p) * Math.max(0, a + b);
558
- }
559
-
560
- /**
561
- * Equivalent to
562
- * const el0 = expectedLoss(prob, m, totLong, totShort, 0, 0);
563
- * const el1 = expectedLoss(prob, m, totLong, totShort, tradeAmt, tradeMgnRate)
564
- * const fee = (el1 - el0) / Math.abs(tradeAmt);
565
- * @param p prob long probability
566
- * @param m max maintenance margin rate (0.18)
567
- * @param tradeAmt trade amount in base currency
568
- * @param tradeMgnRate margin rate for this trade
569
- * @returns dollar fee
570
- */
571
- function expectedLossImpact(p: number, m: number, tradeAmt: number, tradeMgnRate: number) {
572
- m = (0.4 - m) * entropy(p) + m;
573
- let dlm = 0;
574
- let dl = 0;
575
- let dsm = 0;
576
- let ds = 0;
577
- if (tradeAmt > 0) {
578
- dlm = p * tradeAmt * tradeMgnRate;
579
- dl = tradeAmt;
580
- } else if (tradeAmt < 0) {
581
- dsm = (1 - p) * Math.abs(tradeAmt) * tradeMgnRate;
582
- ds = Math.abs(tradeAmt);
583
- }
584
- //long: p * (1 - p) max(0, dl-dlm) = p * (1 - p) max(0, tradeAmt - p * tradeAmt * tradeMgnRate)
585
- const a = dl - dsm;
586
- const b = ds - dlm;
587
- return p * (1 - p) * Math.max(0, a + b);
608
+ // mu0 = max(Rm/lvg, min(Rm, cmin))
609
+ // balance = (mu0 * |k| + k *(sm - s0)) / s3
610
+ // pos value = |k| * Rm / s3
611
+ // at max init lvg: Rm/lvg = min(cmin, Rm)
612
+ // --> margin rate = (mu0 + Rm - R0) / Rm
613
+ const mu0 = Math.min(pm, cmin) + Math.max(0, p0 - pm);
614
+ return (mu0 + pm - p0) / pm;
588
615
  }
589
616
 
590
617
  /**
@@ -597,16 +624,69 @@ function expectedLossImpact(p: number, m: number, tradeAmt: number, tradeMgnRate
597
624
  * @returns dollar fee relative to tradeAmt
598
625
  */
599
626
  export function pmExchangeFee(prob: number, m: number, tradeAmt: number, tradeMgnRate: number): number {
600
- /*
601
- equivalent:
602
- const el0 = expectedLoss(prob, m, totLong, totShort, 0, 0);
603
- const el1 = expectedLoss(prob, m, totLong, totShort, tradeAmt, tradeMgnRate);
604
- const fee = (el1 - el0) / Math.abs(tradeAmt);
605
- */
606
- let fee = expectedLossImpact(prob, m, tradeAmt, tradeMgnRate) / Math.abs(tradeAmt);
627
+ // TODO: port contract logic here
628
+ const [kappa, es] = [0, 0];
629
+ prob = tradeAmt > 0 ? prob : 1 - prob;
630
+ let fee = prob * (1 - kappa);
631
+ const scaledLvg = prob * tradeMgnRate * (1 - fee);
632
+ fee = fee * (1 - prob) - scaledLvg + es;
607
633
  return Math.max(fee, 0.001);
608
634
  }
609
635
 
636
+ export function pmExitFee(varphi: number, varphiBar: number, mu_m: number, m_0: number, sigt: number, jump: number) {
637
+ const pLiq = varphi + mu_m - m_0;
638
+ const kappa = calcKappa(varphiBar, pLiq, sigt);
639
+ let fee = prdMktLvgFee(kappa, varphi, m_0);
640
+ return fee;
641
+ }
642
+
643
+ export function pmOpenFee(varphi: number, varphiBar: number, mu_m: number, m_0: number, sigt: number, jump: number) {
644
+ const pLiq = varphi + mu_m - m_0;
645
+ const kappa = calcKappa(varphiBar, pLiq, sigt);
646
+ const es = calcJumpRisk(kappa, varphiBar, jump);
647
+ const feecap = (1 - varphiBar) * varphiBar - (1 - varphiBar) * m_0;
648
+ let fee = prdMktLvgFee(kappa, varphi, m_0);
649
+ fee = fee + es;
650
+ if (fee > feecap) {
651
+ fee = feecap;
652
+ }
653
+ if (fee < 0.001) {
654
+ fee = 0.001;
655
+ }
656
+ return fee;
657
+ }
658
+
659
+ //sigt = sigma*sqrt(t)
660
+ function calcKappa(varphi: number, varphiLiq: number, sigt: number): number {
661
+ const p = 1 - varphi;
662
+ const pStar = 1 - varphiLiq;
663
+ const x0 = Math.log(p / (1 - p));
664
+ const a = Math.log(pStar / (1 - pStar));
665
+ const kappa = 2 * (1 - cdfNormalStd((a - x0) / sigt));
666
+ return kappa;
667
+ }
668
+
669
+ function calcJumpRisk(kappa: number, varphi: number, jump: number): number {
670
+ jump = Math.floor(jump / 0.05) * 0.05;
671
+ const jr = jump * (1 - varphi * (1 - kappa));
672
+ return jr;
673
+ }
674
+
675
+ //opening leverage fee with cash per contract of m0, without jump risk
676
+ function prdMktLvgFee(kappa: number, varphi: number, m0: number): number {
677
+ const f = (1 - kappa) * varphi * (1 - varphi) - (1 - varphi * (1 - kappa)) * m0;
678
+ return f;
679
+ }
680
+
681
+ function cdfNormalStd(x: number) {
682
+ const t = 1 / (1 + 0.2315419 * Math.abs(x));
683
+ const d = 0.3989423 * Math.exp((-x * x) / 2);
684
+ let prob = d * t * (0.3193815 + t * (-0.3565638 + t * (1.781478 + t * (-1.821256 + t * 1.330274))));
685
+ if (x > 0) {
686
+ prob = 1 - prob;
687
+ }
688
+ return prob;
689
+ }
610
690
  /**
611
691
  * Margin balance for prediction markets
612
692
  * @param pos signed position
@@ -620,45 +700,53 @@ export function pmMarginBalance(pos: number, s2: number, s3: number, ell: number
620
700
  return (pos * s2) / s3 - ell / s3 + mc;
621
701
  }
622
702
 
623
- export function pmExcessBalance(
624
- pos: number,
625
- s2: number,
626
- s3: number,
627
- ell: number,
628
- mc: number,
629
- m: number | undefined
630
- ): number {
631
- return pmMarginBalance(pos, s2, s3, ell, mc) - pmMarginThresh(pos, s2, s3, m);
703
+ export function pmExcessBalance(pos: number, s2: number, s3: number, ell: number, mc: number, m: number): number {
704
+ return pmMarginBalance(pos, s2, s3, ell, mc) - pmMarginThresh(pos, ell, s2, s3, m);
632
705
  }
633
706
 
634
- // finds the liquidation price for prediction markets
635
- // using Newton's algorithm
707
+ /**
708
+ *
709
+ * @param pos Signed position size
710
+ * @param s3 Collateral to quote conversion at spot
711
+ * @param ell Locked-in value
712
+ * @param mc Margin collateral
713
+ * @param baseMarginRate Maintenance margin per contract (mu_m)
714
+ * @param sm Mark price at entry
715
+ * @returns {number} Liquidation price as a probability in the range [0, 1]
716
+ */
636
717
  export function pmFindLiquidationPrice(
637
718
  pos: number,
638
719
  s3: number,
639
720
  ell: number,
640
721
  mc: number,
641
- baseMarginRate: number | undefined,
642
- s2Start: number | undefined = 0.5
722
+ baseMarginRate: number
643
723
  ): number {
644
- const delta_s = 0.01;
645
- let s = 100;
646
- let s_new = s2Start;
647
-
648
- while (Math.abs(s_new - s) > 0.01) {
649
- s = s_new;
650
- const f = Math.pow(pmExcessBalance(pos, s, s3, ell, mc, baseMarginRate), 2);
651
- const ds = (Math.pow(pmExcessBalance(pos, s + delta_s, s3, ell, mc, baseMarginRate), 2) - f) / delta_s;
652
- s_new = s - f / ds;
653
-
654
- if (s_new < 1) {
655
- return 1;
656
- }
657
- if (s_new > 2) {
658
- return 2;
659
- }
724
+ // liq <--> (A) c / |k| < R0 && (B) E < |k| * mu_m
725
+
726
+ // if not (A), return 0 (long) or 1 (short) [no liq]
727
+
728
+ // else, solve for pm:
729
+ // E = c - |k| max(0, s * (p0 - pm)) = |k| * mu_m
730
+ // if c/|k| < mu_m:
731
+ // any number would do --> return 1 (long) or 0 (short)
732
+ // else:
733
+ // pm = p0 - s * (c/|k| - mu_m)
734
+
735
+ const p0 = Math.abs(ell / pos) - 1;
736
+ const R0 = pos > 0 ? p0 : 1 - p0;
737
+ const excessPerCtrct = (mc * s3) / Math.abs(pos) - baseMarginRate; // c/|k| - mu_m, mu_m < CMINUS
738
+
739
+ if (mc * s3 > R0 * Math.abs(pos)) {
740
+ // c > |k| R(p0, s) --> no liquidation
741
+ return probToPrice(pos > 0 ? 0.0001 : 0.9999);
742
+ }
743
+
744
+ if (excessPerCtrct < 0) {
745
+ // already underwater
746
+ return probToPrice(pos > 0 ? 0.9999 : 0.0001);
660
747
  }
661
- return s;
748
+
749
+ return probToPrice(pos > 0 ? p0 - excessPerCtrct : p0 + excessPerCtrct);
662
750
  }
663
751
 
664
752
  /**
@@ -719,19 +807,22 @@ function pmGetDepositAmtForLvgTrade(
719
807
  S3: number,
720
808
  S2Mark: number
721
809
  ): number {
722
- const pnl = (tradeAmt * (S2Mark - price)) / S3;
723
- let p = S2Mark - 1;
724
- if (tradeAmt < 0) {
725
- p = 1 - p;
726
- }
727
- const b = (Math.abs(tradeAmt) * p) / S3 / targetLvg;
728
- const amt = -(pnl - b);
729
- // check:
730
- //bal = amt+pnl
731
- //pos_val = (np.abs(trade_amt) * p) / S3
732
- //lvg = pos_val/bal
733
- //assert(np.abs(lvg-targetLvg)<0.1)
734
- return amt;
810
+ const cmin = 0.05;
811
+ // refer to main contract function for this:
812
+ return getDepositAmountForPredMktLvgTrade(0, 0, 0, tradeAmt, targetLvg, price - 1, S3, S2Mark - 1, cmin);
813
+ // const pnl = (tradeAmt * (S2Mark - price)) / S3;
814
+ // let p = S2Mark - 1;
815
+ // if (tradeAmt < 0) {
816
+ // p = 1 - p;
817
+ // }
818
+ // const b = (Math.abs(tradeAmt) * p) / S3 / targetLvg;
819
+ // const amt = -(pnl - b);
820
+ // // check:
821
+ // //bal = amt+pnl
822
+ // //pos_val = (np.abs(trade_amt) * p) / S3
823
+ // //lvg = pos_val/bal
824
+ // //assert(np.abs(lvg-targetLvg)<0.1)
825
+ // return amt;
735
826
  }
736
827
 
737
828
  /**
@@ -763,16 +854,21 @@ function pmExcessCashAtLvg(
763
854
  Sm: number,
764
855
  S3: number
765
856
  ): number {
857
+ const cmin = 0.05;
858
+ const mu_m = 0.01;
859
+
860
+ const maxLvg = pmMaxLeverage(currentPosition + tradeAmt, Sm - 1, cmin);
861
+ lvg = lvg < maxLvg ? lvg : maxLvg;
766
862
  //determine deposit amount for given leverage
767
863
  const limitPrice = S2 * (1 + Math.sign(tradeAmt) * slippage);
768
864
  const depositFromWallet = pmGetDepositAmtForLvgTrade(tradeAmt, lvg, limitPrice, S3, Sm);
769
- const m0 = 0.18;
865
+
770
866
  //leverage fee
771
867
  let p0 = Sm - 1;
772
868
  if (tradeAmt < 0) {
773
869
  p0 = 2 - Sm; //=1-(Sm-1)
774
870
  }
775
- const feeCc = (Math.abs(tradeAmt) * pmExchangeFee(p0, m0, tradeAmt, 1 / lvg)) / S3;
871
+ const feeCc = (Math.abs(tradeAmt) * pmExchangeFee(p0, mu_m, tradeAmt, 1 / lvg)) / S3;
776
872
 
777
873
  //excess cash
778
874
  let exc = walletBalCC - depositFromWallet - feeCc;
@@ -782,12 +878,15 @@ function pmExcessCashAtLvg(
782
878
  // margin balance
783
879
  let pos = currentPosition + tradeAmt;
784
880
  let p = Sm - 1;
881
+ let entryP = limitPrice - 1;
785
882
  if (pos < 0) {
786
- p = 2 - Sm;
883
+ p = 1 - Sm;
884
+ entryP = 1 - entryP;
787
885
  }
788
- const h = entropy(p);
789
- const tau = m0 + (0.5 - m0) * h;
790
- const thresh = Math.abs(pos) * p * tau;
886
+
887
+ const mu0 = p / lvg + Math.max(0, entryP - p);
888
+ const thresh = Math.abs(pos) * mu0;
889
+
791
890
  const b0 =
792
891
  depositFromWallet +
793
892
  currentCashCC +
@@ -947,7 +1046,7 @@ export function pmFindMaxPersonalTradeSizeAtLeverage(
947
1046
  * @param short Short open OI
948
1047
  * @param sm Mark price (>1)
949
1048
  * @param isBuy True if trade is long
950
- * @param mr Maintenance margin rate
1049
+ * @param mr Margin threshold per contract for liquidation (mu_m)
951
1050
  */
952
1051
  export function pmMaxSignedOpenTradeSize(
953
1052
  long: number,
@@ -957,10 +1056,12 @@ export function pmMaxSignedOpenTradeSize(
957
1056
  mr: number,
958
1057
  ammFundsQC: number
959
1058
  ) {
960
- if (sm < 1) {
1059
+ if (sm <= 1 || sm >= 2) {
1060
+ // closed
961
1061
  return 0;
962
1062
  }
963
- const m = pmMaintenanceMarginRate(isBuy ? 1 : -1, sm, mr);
1063
+ const counterPos = isBuy ? -short : long;
1064
+ const m = pmMaintenanceMarginRate(counterPos, counterPos * sm, sm, mr);
964
1065
  let p = !isBuy ? sm - 1 : 2 - sm;
965
1066
  p = p < 0.01 ? 0.01 : p > 0.99 ? 0.99 : p; // same cap as contract
966
1067
  return isBuy ? (ammFundsQC + m * p * short) / p - long : -(ammFundsQC + m * p * long) / p + short;
@@ -1,7 +1,7 @@
1
1
  import { BigNumberish, JsonRpcProvider, Overrides, Signer, TransactionResponse } from "ethers";
2
2
  import { PayableOverrides } from "./contracts/common";
3
3
  import { IPyth__factory } from "./contracts/factories";
4
- import { ABK64x64ToFloat, entropy, floatToABK64x64 } from "./d8XMath";
4
+ import { ABK64x64ToFloat, floatToABK64x64 } from "./d8XMath";
5
5
  import type { NodeSDKConfig, PriceFeedSubmission } from "./nodeSDKTypes";
6
6
  import WriteAccessHandler from "./writeAccessHandler";
7
7
 
@@ -282,8 +282,10 @@ export default class LiquidatorTool extends WriteAccessHandler {
282
282
  let threshold: number;
283
283
  if (this.isPredictionMarket(symbol)) {
284
284
  const idx_markPrice = 8;
285
+ const idx_lockedInValue = 5;
285
286
  const markPrice = ABK64x64ToFloat(traderState[idx_markPrice]);
286
- threshold = LiquidatorTool.maintenanceMarginPredMkts(maintMgnRate, pos, coll2quote, markPrice);
287
+ const ell = ABK64x64ToFloat(traderState[idx_lockedInValue]);
288
+ threshold = LiquidatorTool.maintenanceMarginPredMkts(maintMgnRate, pos, coll2quote, markPrice, ell);
287
289
  } else {
288
290
  const base2collateral = indexPrices[0] / coll2quote;
289
291
  threshold = Math.abs(pos * base2collateral * maintMgnRate);
@@ -291,14 +293,18 @@ export default class LiquidatorTool extends WriteAccessHandler {
291
293
  return marginbalance >= threshold;
292
294
  }
293
295
 
294
- public static maintenanceMarginPredMkts(maintMgnRateBase: number, pos: number, s3: number, markPx: number) {
295
- let p = markPx - 1;
296
- // p: price = 1+prob
297
- if (pos < 0) {
298
- p = 1 - p;
299
- }
300
- const tau = maintMgnRateBase + (0.4 - maintMgnRateBase) * entropy(p);
301
- return (Math.abs(pos) * p * tau) / s3;
296
+ public static maintenanceMarginPredMkts(
297
+ maintMgnRateBase: number,
298
+ pos: number,
299
+ s3: number,
300
+ markPx: number,
301
+ ell: number
302
+ ) {
303
+ const s = pos > 0 ? 1 : -1; // pos is
304
+ const R = pos == 0 ? markPx - 1 : s > 0 ? Math.abs(ell / pos) - 1 : 2 - Math.abs(ell / pos);
305
+ const Rm = s > 0 ? markPx - 1 : 2 - markPx;
306
+ const L = Math.max(0, s * (R - Rm));
307
+ return (Math.abs(pos) * Math.min(maintMgnRateBase + L, R)) / s3; // liquidated if E < that
302
308
  }
303
309
 
304
310
  /**