@d8x/perpetuals-sdk 2.0.12-alpha → 2.1.0-alpha2

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 (252) hide show
  1. package/dist/cjs/abi/IPerpetualManager.json +124 -3
  2. package/dist/cjs/abi/OracleFactory.json +94 -25
  3. package/dist/cjs/abi/PerpetualManagerProxy.json +212 -2
  4. package/dist/cjs/brokerTool.d.ts +5 -1
  5. package/dist/cjs/brokerTool.js +14 -1
  6. package/dist/cjs/brokerTool.js.map +1 -1
  7. package/dist/cjs/contracts/IPerpetualManager.d.ts +74 -10
  8. package/dist/cjs/contracts/OracleFactory.d.ts +69 -20
  9. package/dist/cjs/contracts/PerpetualManagerProxy.d.ts +109 -4
  10. package/dist/cjs/contracts/factories/IPerpetualManager__factory.d.ts +95 -3
  11. package/dist/cjs/contracts/factories/IPerpetualManager__factory.js +124 -3
  12. package/dist/cjs/contracts/factories/IPerpetualManager__factory.js.map +1 -1
  13. package/dist/cjs/contracts/factories/OracleFactory__factory.d.ts +75 -20
  14. package/dist/cjs/contracts/factories/OracleFactory__factory.js +94 -25
  15. package/dist/cjs/contracts/factories/OracleFactory__factory.js.map +1 -1
  16. package/dist/cjs/contracts/factories/PerpetualManagerProxy__factory.d.ts +159 -2
  17. package/dist/cjs/contracts/factories/PerpetualManagerProxy__factory.js +212 -2
  18. package/dist/cjs/contracts/factories/PerpetualManagerProxy__factory.js.map +1 -1
  19. package/dist/cjs/d8XMath.d.ts +44 -1
  20. package/dist/cjs/d8XMath.js +236 -3
  21. package/dist/cjs/d8XMath.js.map +1 -1
  22. package/dist/cjs/liquidatorTool.d.ts +1 -0
  23. package/dist/cjs/liquidatorTool.js +24 -7
  24. package/dist/cjs/liquidatorTool.js.map +1 -1
  25. package/dist/cjs/marketData.d.ts +42 -20
  26. package/dist/cjs/marketData.js +261 -188
  27. package/dist/cjs/marketData.js.map +1 -1
  28. package/dist/cjs/nodeSDKTypes.d.ts +24 -2
  29. package/dist/cjs/nodeSDKTypes.js.map +1 -1
  30. package/dist/cjs/orderExecutorTool.d.ts +3 -3
  31. package/dist/cjs/orderExecutorTool.js +38 -13
  32. package/dist/cjs/orderExecutorTool.js.map +1 -1
  33. package/dist/cjs/perpetualDataHandler.d.ts +22 -12
  34. package/dist/cjs/perpetualDataHandler.js +59 -44
  35. package/dist/cjs/perpetualDataHandler.js.map +1 -1
  36. package/dist/cjs/perpetualEventHandler.d.ts +1 -1
  37. package/dist/cjs/perpetualEventHandler.js +6 -7
  38. package/dist/cjs/perpetualEventHandler.js.map +1 -1
  39. package/dist/cjs/polyMktsPxFeed.d.ts +6 -4
  40. package/dist/cjs/polyMktsPxFeed.js +24 -3
  41. package/dist/cjs/polyMktsPxFeed.js.map +1 -1
  42. package/dist/cjs/priceFeeds.d.ts +6 -7
  43. package/dist/cjs/priceFeeds.js +36 -14
  44. package/dist/cjs/priceFeeds.js.map +1 -1
  45. package/dist/cjs/version.d.ts +1 -1
  46. package/dist/cjs/version.js +1 -1
  47. package/dist/esm/abi/IPerpetualManager.json +124 -3
  48. package/dist/esm/abi/OracleFactory.json +94 -25
  49. package/dist/esm/abi/PerpetualManagerProxy.json +212 -2
  50. package/dist/esm/brokerTool.d.ts +5 -1
  51. package/dist/esm/brokerTool.js +15 -2
  52. package/dist/esm/brokerTool.js.map +1 -1
  53. package/dist/esm/contracts/IPerpetualManager.d.ts +74 -10
  54. package/dist/esm/contracts/OracleFactory.d.ts +69 -20
  55. package/dist/esm/contracts/PerpetualManagerProxy.d.ts +109 -4
  56. package/dist/esm/contracts/factories/IPerpetualManager__factory.d.ts +95 -3
  57. package/dist/esm/contracts/factories/IPerpetualManager__factory.js +124 -3
  58. package/dist/esm/contracts/factories/IPerpetualManager__factory.js.map +1 -1
  59. package/dist/esm/contracts/factories/OracleFactory__factory.d.ts +75 -20
  60. package/dist/esm/contracts/factories/OracleFactory__factory.js +94 -25
  61. package/dist/esm/contracts/factories/OracleFactory__factory.js.map +1 -1
  62. package/dist/{cjs/contracts/factories/MockToken__factory.d.ts → esm/contracts/factories/PerpStorage__factory.d.ts} +115 -128
  63. package/dist/esm/contracts/factories/{MockToken__factory.js → PerpStorage__factory.js} +128 -139
  64. package/dist/esm/contracts/factories/PerpStorage__factory.js.map +1 -0
  65. package/dist/esm/contracts/factories/PerpetualManagerProxy__factory.d.ts +159 -2
  66. package/dist/esm/contracts/factories/PerpetualManagerProxy__factory.js +212 -2
  67. package/dist/esm/contracts/factories/PerpetualManagerProxy__factory.js.map +1 -1
  68. package/dist/esm/d8XMath.d.ts +44 -1
  69. package/dist/esm/d8XMath.js +229 -2
  70. package/dist/esm/d8XMath.js.map +1 -1
  71. package/dist/esm/liquidatorTool.d.ts +1 -0
  72. package/dist/esm/liquidatorTool.js +25 -8
  73. package/dist/esm/liquidatorTool.js.map +1 -1
  74. package/dist/esm/marketData.d.ts +42 -20
  75. package/dist/esm/marketData.js +263 -190
  76. package/dist/esm/marketData.js.map +1 -1
  77. package/dist/esm/nodeSDKTypes.d.ts +24 -2
  78. package/dist/esm/nodeSDKTypes.js.map +1 -1
  79. package/dist/esm/orderExecutorTool.d.ts +3 -3
  80. package/dist/esm/orderExecutorTool.js +38 -13
  81. package/dist/esm/orderExecutorTool.js.map +1 -1
  82. package/dist/esm/perpetualDataHandler.d.ts +22 -12
  83. package/dist/esm/perpetualDataHandler.js +60 -45
  84. package/dist/esm/perpetualDataHandler.js.map +1 -1
  85. package/dist/esm/perpetualEventHandler.d.ts +1 -1
  86. package/dist/esm/perpetualEventHandler.js +6 -7
  87. package/dist/esm/perpetualEventHandler.js.map +1 -1
  88. package/dist/esm/polyMktsPxFeed.d.ts +6 -4
  89. package/dist/esm/polyMktsPxFeed.js +24 -3
  90. package/dist/esm/polyMktsPxFeed.js.map +1 -1
  91. package/dist/esm/priceFeeds.d.ts +6 -7
  92. package/dist/esm/priceFeeds.js +36 -14
  93. package/dist/esm/priceFeeds.js.map +1 -1
  94. package/dist/esm/version.d.ts +1 -1
  95. package/dist/esm/version.js +1 -1
  96. package/package.json +1 -1
  97. package/src/abi/IPerpetualManager.json +124 -3
  98. package/src/abi/OracleFactory.json +523 -454
  99. package/src/abi/PerpetualManagerProxy.json +1596 -1386
  100. package/src/brokerTool.ts +16 -2
  101. package/src/contracts/IPerpetualManager.ts +107 -7
  102. package/src/contracts/OracleFactory.ts +100 -26
  103. package/src/contracts/PerpetualManagerProxy.ts +192 -3
  104. package/src/contracts/factories/IPerpetualManager__factory.ts +124 -3
  105. package/src/contracts/factories/OracleFactory__factory.ts +94 -25
  106. package/src/contracts/factories/PerpetualManagerProxy__factory.ts +212 -2
  107. package/src/d8XMath.ts +304 -2
  108. package/src/liquidatorTool.ts +29 -14
  109. package/src/marketData.ts +415 -238
  110. package/src/nodeSDKTypes.ts +30 -2
  111. package/src/orderExecutorTool.ts +48 -20
  112. package/src/perpetualDataHandler.ts +87 -45
  113. package/src/perpetualEventHandler.ts +6 -7
  114. package/src/polyMktsPxFeed.ts +30 -5
  115. package/src/priceFeeds.ts +41 -17
  116. package/src/version.ts +1 -1
  117. package/dist/cjs/abi/BeaconProxy.json +0 -71
  118. package/dist/cjs/abi/Maintainer.json +0 -774
  119. package/dist/cjs/abi/MockToken.json +0 -347
  120. package/dist/cjs/abi/UUPSUpgradeable.json +0 -104
  121. package/dist/cjs/abi/WeETH.json +0 -310
  122. package/dist/cjs/abi-zkevm/LimitOrderBook.json +0 -910
  123. package/dist/cjs/abi-zkevm/LimitOrderBookFactory.json +0 -236
  124. package/dist/cjs/contracts/BeaconProxy.d.ts +0 -63
  125. package/dist/cjs/contracts/BeaconProxy.js +0 -3
  126. package/dist/cjs/contracts/BeaconProxy.js.map +0 -1
  127. package/dist/cjs/contracts/Maintainer.d.ts +0 -799
  128. package/dist/cjs/contracts/Maintainer.js +0 -3
  129. package/dist/cjs/contracts/Maintainer.js.map +0 -1
  130. package/dist/cjs/contracts/MockToken.d.ts +0 -263
  131. package/dist/cjs/contracts/MockToken.js +0 -3
  132. package/dist/cjs/contracts/MockToken.js.map +0 -1
  133. package/dist/cjs/contracts/UUPSUpgradeable.d.ts +0 -118
  134. package/dist/cjs/contracts/UUPSUpgradeable.js +0 -3
  135. package/dist/cjs/contracts/UUPSUpgradeable.js.map +0 -1
  136. package/dist/cjs/contracts/WeETH.d.ts +0 -503
  137. package/dist/cjs/contracts/WeETH.js +0 -3
  138. package/dist/cjs/contracts/WeETH.js.map +0 -1
  139. package/dist/cjs/contracts/factories/BeaconProxy__factory.d.ts +0 -61
  140. package/dist/cjs/contracts/factories/BeaconProxy__factory.js +0 -89
  141. package/dist/cjs/contracts/factories/BeaconProxy__factory.js.map +0 -1
  142. package/dist/cjs/contracts/factories/Maintainer__factory.d.ts +0 -609
  143. package/dist/cjs/contracts/factories/Maintainer__factory.js +0 -792
  144. package/dist/cjs/contracts/factories/Maintainer__factory.js.map +0 -1
  145. package/dist/cjs/contracts/factories/MockToken__factory.js +0 -365
  146. package/dist/cjs/contracts/factories/MockToken__factory.js.map +0 -1
  147. package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.d.ts +0 -87
  148. package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.js +0 -122
  149. package/dist/cjs/contracts/factories/UUPSUpgradeable__factory.js.map +0 -1
  150. package/dist/cjs/contracts/factories/WeETH__factory.d.ts +0 -545
  151. package/dist/cjs/contracts/factories/WeETH__factory.js +0 -721
  152. package/dist/cjs/contracts/factories/WeETH__factory.js.map +0 -1
  153. package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.d.ts +0 -4136
  154. package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.js +0 -5324
  155. package/dist/cjs/contracts/factories/lean0/IPerpetualManager__factory.js.map +0 -1
  156. package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.d.ts +0 -189
  157. package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.js +0 -254
  158. package/dist/cjs/contracts/factories/lean0/LimitOrderBookFactory__factory.js.map +0 -1
  159. package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.d.ts +0 -715
  160. package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.js +0 -928
  161. package/dist/cjs/contracts/factories/lean0/LimitOrderBook__factory.js.map +0 -1
  162. package/dist/cjs/contracts/factories/lean0/ShareToken__factory.d.ts +0 -344
  163. package/dist/cjs/contracts/factories/lean0/ShareToken__factory.js +0 -456
  164. package/dist/cjs/contracts/factories/lean0/ShareToken__factory.js.map +0 -1
  165. package/dist/cjs/contracts/factories/lean0/index.d.ts +0 -4
  166. package/dist/cjs/contracts/factories/lean0/index.js +0 -15
  167. package/dist/cjs/contracts/factories/lean0/index.js.map +0 -1
  168. package/dist/cjs/contracts/lean0/IPerpetualManager.d.ts +0 -2821
  169. package/dist/cjs/contracts/lean0/IPerpetualManager.js +0 -3
  170. package/dist/cjs/contracts/lean0/IPerpetualManager.js.map +0 -1
  171. package/dist/cjs/contracts/lean0/LimitOrderBook.d.ts +0 -533
  172. package/dist/cjs/contracts/lean0/LimitOrderBook.js +0 -3
  173. package/dist/cjs/contracts/lean0/LimitOrderBook.js.map +0 -1
  174. package/dist/cjs/contracts/lean0/LimitOrderBookFactory.d.ts +0 -210
  175. package/dist/cjs/contracts/lean0/LimitOrderBookFactory.js +0 -3
  176. package/dist/cjs/contracts/lean0/LimitOrderBookFactory.js.map +0 -1
  177. package/dist/cjs/contracts/lean0/ShareToken.d.ts +0 -320
  178. package/dist/cjs/contracts/lean0/ShareToken.js +0 -3
  179. package/dist/cjs/contracts/lean0/ShareToken.js.map +0 -1
  180. package/dist/cjs/contracts/lean0/index.d.ts +0 -4
  181. package/dist/cjs/contracts/lean0/index.js +0 -3
  182. package/dist/cjs/contracts/lean0/index.js.map +0 -1
  183. package/dist/esm/abi/BeaconProxy.json +0 -71
  184. package/dist/esm/abi/Maintainer.json +0 -774
  185. package/dist/esm/abi/MockToken.json +0 -347
  186. package/dist/esm/abi/UUPSUpgradeable.json +0 -104
  187. package/dist/esm/abi/WeETH.json +0 -310
  188. package/dist/esm/abi/lean0/IPerpetualManager.json +0 -5306
  189. package/dist/esm/abi/lean0/LimitOrderBook.json +0 -910
  190. package/dist/esm/abi/lean0/LimitOrderBookFactory.json +0 -236
  191. package/dist/esm/abi/lean0/ShareToken.json +0 -438
  192. package/dist/esm/abi-zkevm/LimitOrderBook.json +0 -910
  193. package/dist/esm/abi-zkevm/LimitOrderBookFactory.json +0 -236
  194. package/dist/esm/contracts/BeaconProxy.d.ts +0 -63
  195. package/dist/esm/contracts/BeaconProxy.js +0 -2
  196. package/dist/esm/contracts/BeaconProxy.js.map +0 -1
  197. package/dist/esm/contracts/Maintainer.d.ts +0 -799
  198. package/dist/esm/contracts/Maintainer.js +0 -2
  199. package/dist/esm/contracts/Maintainer.js.map +0 -1
  200. package/dist/esm/contracts/MockToken.d.ts +0 -263
  201. package/dist/esm/contracts/MockToken.js +0 -2
  202. package/dist/esm/contracts/MockToken.js.map +0 -1
  203. package/dist/esm/contracts/UUPSUpgradeable.d.ts +0 -118
  204. package/dist/esm/contracts/UUPSUpgradeable.js +0 -2
  205. package/dist/esm/contracts/UUPSUpgradeable.js.map +0 -1
  206. package/dist/esm/contracts/WeETH.d.ts +0 -503
  207. package/dist/esm/contracts/WeETH.js +0 -2
  208. package/dist/esm/contracts/WeETH.js.map +0 -1
  209. package/dist/esm/contracts/factories/BeaconProxy__factory.d.ts +0 -61
  210. package/dist/esm/contracts/factories/BeaconProxy__factory.js +0 -85
  211. package/dist/esm/contracts/factories/BeaconProxy__factory.js.map +0 -1
  212. package/dist/esm/contracts/factories/Maintainer__factory.d.ts +0 -609
  213. package/dist/esm/contracts/factories/Maintainer__factory.js +0 -788
  214. package/dist/esm/contracts/factories/Maintainer__factory.js.map +0 -1
  215. package/dist/esm/contracts/factories/MockToken__factory.d.ts +0 -273
  216. package/dist/esm/contracts/factories/MockToken__factory.js.map +0 -1
  217. package/dist/esm/contracts/factories/UUPSUpgradeable__factory.d.ts +0 -87
  218. package/dist/esm/contracts/factories/UUPSUpgradeable__factory.js +0 -118
  219. package/dist/esm/contracts/factories/UUPSUpgradeable__factory.js.map +0 -1
  220. package/dist/esm/contracts/factories/WeETH__factory.d.ts +0 -545
  221. package/dist/esm/contracts/factories/WeETH__factory.js +0 -717
  222. package/dist/esm/contracts/factories/WeETH__factory.js.map +0 -1
  223. package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.d.ts +0 -4136
  224. package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.js +0 -5320
  225. package/dist/esm/contracts/factories/lean0/IPerpetualManager__factory.js.map +0 -1
  226. package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.d.ts +0 -189
  227. package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.js +0 -250
  228. package/dist/esm/contracts/factories/lean0/LimitOrderBookFactory__factory.js.map +0 -1
  229. package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.d.ts +0 -715
  230. package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.js +0 -924
  231. package/dist/esm/contracts/factories/lean0/LimitOrderBook__factory.js.map +0 -1
  232. package/dist/esm/contracts/factories/lean0/ShareToken__factory.d.ts +0 -344
  233. package/dist/esm/contracts/factories/lean0/ShareToken__factory.js +0 -452
  234. package/dist/esm/contracts/factories/lean0/ShareToken__factory.js.map +0 -1
  235. package/dist/esm/contracts/factories/lean0/index.d.ts +0 -4
  236. package/dist/esm/contracts/factories/lean0/index.js +0 -8
  237. package/dist/esm/contracts/factories/lean0/index.js.map +0 -1
  238. package/dist/esm/contracts/lean0/IPerpetualManager.d.ts +0 -2821
  239. package/dist/esm/contracts/lean0/IPerpetualManager.js +0 -2
  240. package/dist/esm/contracts/lean0/IPerpetualManager.js.map +0 -1
  241. package/dist/esm/contracts/lean0/LimitOrderBook.d.ts +0 -533
  242. package/dist/esm/contracts/lean0/LimitOrderBook.js +0 -2
  243. package/dist/esm/contracts/lean0/LimitOrderBook.js.map +0 -1
  244. package/dist/esm/contracts/lean0/LimitOrderBookFactory.d.ts +0 -210
  245. package/dist/esm/contracts/lean0/LimitOrderBookFactory.js +0 -2
  246. package/dist/esm/contracts/lean0/LimitOrderBookFactory.js.map +0 -1
  247. package/dist/esm/contracts/lean0/ShareToken.d.ts +0 -320
  248. package/dist/esm/contracts/lean0/ShareToken.js +0 -2
  249. package/dist/esm/contracts/lean0/ShareToken.js.map +0 -1
  250. package/dist/esm/contracts/lean0/index.d.ts +0 -4
  251. package/dist/esm/contracts/lean0/index.js +0 -2
  252. package/dist/esm/contracts/lean0/index.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { Contract, formatUnits, Interface, JsonRpcProvider } from "ethers";
2
- import { BUY_SIDE, CLOSED_SIDE, COLLATERAL_CURRENCY_BASE, COLLATERAL_CURRENCY_QUANTO, CollaterlCCY, ERC20_ABI, MULTICALL_ADDRESS, ORDER_TYPE_MARKET, PERP_STATE_STR, SELL_SIDE, ZERO_ADDRESS, ZERO_ORDER_ID, } from "./constants";
2
+ import { BUY_SIDE, CLOSED_SIDE, COLLATERAL_CURRENCY_BASE, COLLATERAL_CURRENCY_QUANTO, ERC20_ABI, MULTICALL_ADDRESS, ORDER_TYPE_MARKET, PERP_STATE_STR, SELL_SIDE, ZERO_ADDRESS, ZERO_ORDER_ID, } from "./constants";
3
3
  import { ERC20__factory, Multicall3__factory, } from "./contracts";
4
- import { ABK64x64ToFloat, calculateLiquidationPriceCollateralBase, calculateLiquidationPriceCollateralQuanto, calculateLiquidationPriceCollateralQuote, dec18ToFloat, decNToFloat, floatToABK64x64, getDepositAmountForLvgTrade, getMaxSignedPositionSize, } from "./d8XMath";
4
+ import { ABK64x64ToFloat, dec18ToFloat, decNToFloat, floatToABK64x64, getDepositAmountForLvgTrade, getMaxSignedPositionSize, pmExchangeFee, pmFindMaxTradeSize, } from "./d8XMath";
5
5
  import PerpetualDataHandler from "./perpetualDataHandler";
6
6
  import { contractSymbolToSymbol, toBytes4 } from "./utils";
7
7
  /**
@@ -281,7 +281,8 @@ export default class MarketData extends PerpetualDataHandler {
281
281
  */
282
282
  async _positionRiskForTraderInPerpetual(traderAddr, symbol, provider, overrides) {
283
283
  let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
284
- let mgnAcct = await PerpetualDataHandler.getMarginAccount(traderAddr, symbol, this.symbolToPerpStaticInfo, new Contract(this.proxyAddr, this.config.proxyABI, provider), [obj.idxPrices[0], obj.idxPrices[1]], overrides);
284
+ const isPred = this.isPredictionMarket(symbol);
285
+ let mgnAcct = await PerpetualDataHandler.getMarginAccount(traderAddr, symbol, this.symbolToPerpStaticInfo, new Contract(this.proxyAddr, this.config.proxyABI, provider), obj, isPred, overrides);
285
286
  return mgnAcct;
286
287
  }
287
288
  /**
@@ -293,122 +294,67 @@ export default class MarketData extends PerpetualDataHandler {
293
294
  */
294
295
  async _positionRiskForTraderInPerpetuals(traderAddr, symbols, provider, overrides) {
295
296
  const MAX_SYMBOLS_PER_CALL = 10;
296
- const S2S3 = new Array();
297
+ const pxInfo = new Array();
297
298
  for (let i = 0; i < symbols.length; i++) {
298
299
  let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbols[i]);
299
- S2S3.push([obj.idxPrices[0], obj.idxPrices[1]]);
300
+ pxInfo.push(obj);
300
301
  }
301
302
  let mgnAcct = [];
302
303
  let callSymbols = symbols.slice(0, MAX_SYMBOLS_PER_CALL);
303
- let pxS2S3 = S2S3.slice(0, MAX_SYMBOLS_PER_CALL);
304
+ let _px = pxInfo.slice(0, MAX_SYMBOLS_PER_CALL);
304
305
  while (callSymbols.length > 0) {
305
- let acc = await PerpetualDataHandler.getMarginAccounts(Array(callSymbols.length).fill(traderAddr), callSymbols, this.symbolToPerpStaticInfo, Multicall3__factory.connect(this.config.multicall ?? MULTICALL_ADDRESS, provider), new Contract(this.proxyAddr, this.config.proxyABI, provider), pxS2S3, overrides);
306
+ const isPred = callSymbols.map((_sym) => this.isPredictionMarket(_sym));
307
+ let acc = await PerpetualDataHandler.getMarginAccounts(Array(callSymbols.length).fill(traderAddr), callSymbols, this.symbolToPerpStaticInfo, Multicall3__factory.connect(this.config.multicall ?? MULTICALL_ADDRESS, provider), new Contract(this.proxyAddr, this.config.proxyABI, provider), _px, isPred, overrides);
306
308
  mgnAcct = mgnAcct.concat(acc);
307
309
  callSymbols = symbols.slice(mgnAcct.length, mgnAcct.length + MAX_SYMBOLS_PER_CALL);
308
- pxS2S3 = S2S3.slice(mgnAcct.length, mgnAcct.length + MAX_SYMBOLS_PER_CALL);
310
+ _px = pxInfo.slice(mgnAcct.length, mgnAcct.length + MAX_SYMBOLS_PER_CALL);
309
311
  }
310
312
  return mgnAcct;
311
313
  }
312
- /**
313
- * Estimates what the position risk will be if a given order is executed.
314
- * @param traderAddr Address of trader
315
- * @param order Order to be submitted
316
- * @param account Position risk before trade. Defaults to current position if not given.
317
- * @param indexPriceInfo Index prices and market status (open/closed). Defaults to current market status if not given.
318
- * @returns Position risk after trade, including order cost and maximal trade sizes for position
319
- * @example
320
- * import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
321
- * async function main() {
322
- * console.log(MarketData);
323
- * // setup
324
- * const config = PerpetualDataHandler.readSDKConfig("cardona");
325
- * const mktData = new MarketData(config);
326
- * await mktData.createProxyInstance();
327
- * const order: Order = {
328
- * symbol: "MATIC-USD-MATIC",
329
- * side: "BUY",
330
- * type: "MARKET",
331
- * quantity: 100,
332
- * leverage: 2,
333
- * executionTimestamp: Date.now()/1000,
334
- * };
335
- * // Get position risk conditional on this order being executed
336
- * const posRisk = await mktData.positionRiskOnTrade("0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B", order);
337
- * console.log(posRisk);
338
- * }
339
- * main();
340
- */
341
- async positionRiskOnTrade(traderAddr, order, account, indexPriceInfo, overrides) {
314
+ async dataForPositionRiskOnTrade(symbol, traderAddr, tradeAmountBC, indexPriceInfo, signedPositionNotionalBaseCCY, overrides) {
342
315
  if (this.proxyContract == null || this.multicall == null) {
343
316
  throw Error("no proxy contract initialized. Use createProxyInstance().");
344
317
  }
345
- // fetch prices
346
- if (indexPriceInfo == undefined) {
347
- let obj = await this.priceFeedGetter.fetchPricesForPerpetual(order.symbol);
348
- indexPriceInfo = [obj.idxPrices[0], obj.idxPrices[1], obj.mktClosed[0], obj.mktClosed[1]];
349
- }
350
- // override total fee
351
- let tradingFeeTbps;
352
- if (overrides) {
353
- ({ tradingFeeTbps, ...overrides } = overrides);
354
- }
355
- // signed trade amount
356
- let tradeAmountBC = Math.abs(order.quantity) * (order.side == BUY_SIDE ? 1 : -1);
357
- const accountGiven = account !== undefined;
318
+ const isPredMkt = this.isPredictionMarket(symbol);
358
319
  // create all calls
359
- const poolId = PerpetualDataHandler._getPoolIdFromSymbol(order.symbol, this.poolStaticInfos);
360
- const perpId = PerpetualDataHandler.symbolToPerpetualId(order.symbol, this.symbolToPerpStaticInfo);
361
- const fS2S3 = [indexPriceInfo[0], indexPriceInfo[1]].map((x) => floatToABK64x64(x));
320
+ const perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
321
+ const [fS2, fS3, fEma] = [indexPriceInfo.s2, indexPriceInfo.s3, indexPriceInfo.ema].map((x) => floatToABK64x64(x));
362
322
  const proxyCalls = [
363
323
  // 0: traderState
364
324
  {
365
325
  target: this.proxyContract.target,
366
326
  allowFailure: true,
367
- callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, fS2S3]),
368
- },
369
- // 1: ammState
370
- {
371
- target: this.proxyContract.target,
372
- allowFailure: true,
373
- callData: this.proxyContract.interface.encodeFunctionData("getAMMState", [perpId, fS2S3]),
374
- },
375
- // 2: exchangeFee
376
- {
377
- target: this.proxyContract.target,
378
- allowFailure: false,
379
- callData: this.proxyContract.interface.encodeFunctionData("queryExchangeFee", [
380
- poolId,
381
- traderAddr,
382
- order.brokerAddr ?? ZERO_ADDRESS,
383
- ]),
327
+ callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, [fEma, fS3]]),
384
328
  },
385
- // 3: perpetual price
329
+ // 1: perpetual price
386
330
  {
387
331
  target: this.proxyContract.target,
388
332
  allowFailure: true,
389
333
  callData: this.proxyContract.interface.encodeFunctionData("queryPerpetualPrice", [
390
334
  perpId,
391
335
  floatToABK64x64(tradeAmountBC),
392
- fS2S3,
336
+ [fS2, fS3],
337
+ indexPriceInfo.conf,
338
+ indexPriceInfo.predMktCLOBParams,
393
339
  ]),
394
340
  },
395
- // 4: max long pos
341
+ // 2: max long pos
396
342
  {
397
343
  target: this.proxyContract.target,
398
344
  allowFailure: false,
399
345
  callData: this.proxyContract.interface.encodeFunctionData("getMaxSignedOpenTradeSizeForPos", [
400
346
  perpId,
401
- account ? floatToABK64x64(account.positionNotionalBaseCCY * (account.side === BUY_SIDE ? 1 : -1)) : 0n,
347
+ floatToABK64x64(signedPositionNotionalBaseCCY),
402
348
  true,
403
349
  ]),
404
350
  },
405
- // 5: max short pos
351
+ // 3: max short pos
406
352
  {
407
353
  target: this.proxyContract.target,
408
354
  allowFailure: false,
409
355
  callData: this.proxyContract.interface.encodeFunctionData("getMaxSignedOpenTradeSizeForPos", [
410
356
  perpId,
411
- account ? floatToABK64x64(account.positionNotionalBaseCCY * (account.side === BUY_SIDE ? 1 : -1)) : 0n,
357
+ floatToABK64x64(signedPositionNotionalBaseCCY),
412
358
  false,
413
359
  ]),
414
360
  },
@@ -416,44 +362,84 @@ export default class MarketData extends PerpetualDataHandler {
416
362
  // multicall
417
363
  const encodedResults = await this.multicall.aggregate3.staticCall(proxyCalls, (overrides || {}));
418
364
  // positionRisk to apply this trade on: if not given, defaults to the current trader's position
419
- if (!account) {
420
- let traderState;
421
- if (encodedResults[0].success) {
422
- traderState = this.proxyContract.interface.decodeFunctionResult("getTraderState", encodedResults[0].returnData)[0];
423
- }
424
- else {
425
- traderState = await this.proxyContract.getTraderState(perpId, traderAddr, fS2S3);
426
- }
427
- account = MarketData.buildMarginAccountFromState(order.symbol, traderState, this.symbolToPerpStaticInfo, [
428
- indexPriceInfo[0],
429
- indexPriceInfo[1],
430
- ]);
431
- }
432
- // perpetualState, for prices
433
- let ammState;
434
- if (encodedResults[1].success) {
435
- ammState = this.proxyContract.interface.decodeFunctionResult("getAMMState", encodedResults[1].returnData)[0];
365
+ let traderState;
366
+ if (encodedResults[0].success) {
367
+ traderState = this.proxyContract.interface.decodeFunctionResult("getTraderState", encodedResults[0].returnData)[0];
436
368
  }
437
369
  else {
438
- ammState = await this.proxyContract.getAMMState(perpId, fS2S3);
370
+ traderState = await this.proxyContract.getTraderState(perpId, traderAddr, [fEma, fS3]);
439
371
  }
440
- const perpetualState = PerpetualDataHandler._parseAMMState(order.symbol, ammState, [0n, 0n], // not used below
441
- indexPriceInfo, this.symbolToPerpStaticInfo);
442
- let [S2, S3, Sm] = [perpetualState.indexPrice, perpetualState.collToQuoteIndexPrice, perpetualState.markPrice];
443
- // exchange fee based on this trader's address (volume, token holding, etc) and his broker address (if any)
444
- const exchangeFeeTbps = this.proxyContract.interface.decodeFunctionResult("queryExchangeFee", encodedResults[2].returnData)[0];
372
+ const account = MarketData.buildMarginAccountFromState(symbol, traderState, this.symbolToPerpStaticInfo, indexPriceInfo, isPredMkt);
445
373
  // amm price for this trade amount
446
374
  let ammPrice;
447
375
  {
448
376
  let fPrice;
449
- if (encodedResults[3].success) {
450
- fPrice = this.proxyContract.interface.decodeFunctionResult("queryPerpetualPrice", encodedResults[3].returnData)[0];
377
+ if (encodedResults[1].success) {
378
+ fPrice = this.proxyContract.interface.decodeFunctionResult("queryPerpetualPrice", encodedResults[1].returnData)[0];
451
379
  }
452
380
  else {
453
- fPrice = await this.proxyContract.queryPerpetualPrice(perpId, floatToABK64x64(tradeAmountBC), fS2S3);
381
+ fPrice = await this.proxyContract.queryPerpetualPrice(perpId, floatToABK64x64(tradeAmountBC), [indexPriceInfo.s2, indexPriceInfo.s3], indexPriceInfo.conf, indexPriceInfo.predMktCLOBParams);
454
382
  }
455
383
  ammPrice = ABK64x64ToFloat(fPrice);
456
384
  }
385
+ // max buy
386
+ const fMaxLong = this.proxyContract.interface.decodeFunctionResult("getMaxSignedOpenTradeSizeForPos", encodedResults[2].returnData)[0];
387
+ const maxLongTrade = Math.max(0, ABK64x64ToFloat(fMaxLong) - signedPositionNotionalBaseCCY);
388
+ // max sell
389
+ const fMaxShort = this.proxyContract.interface.decodeFunctionResult("getMaxSignedOpenTradeSizeForPos", encodedResults[3].returnData)[0];
390
+ const maxShortTrade = Math.max(0, Math.abs(ABK64x64ToFloat(fMaxShort)) - signedPositionNotionalBaseCCY);
391
+ return { account: account, ammPrice: ammPrice, maxShortTrade: maxShortTrade, maxLongTrade: maxLongTrade };
392
+ }
393
+ /**
394
+ * Estimates what the position risk will be if a given order is executed.
395
+ * @param traderAddr Address of trader
396
+ * @param order Order to be submitted
397
+ * @param signedPositionNotionalBaseCCY signed position notional of current position (before trade)
398
+ * @param tradingFeeTbps trading fee in tenth of basis points (exchange fee and broker fee)
399
+ * @param indexPriceInfo Index prices and market status (open/closed). Defaults to current market status if not given.
400
+ * @returns Position risk after trade, including order cost and maximal trade sizes for position
401
+ * @example
402
+ * import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
403
+ * async function main() {
404
+ * console.log(MarketData);
405
+ * // setup
406
+ * const config = PerpetualDataHandler.readSDKConfig("cardona");
407
+ * const mktData = new MarketData(config);
408
+ * await mktData.createProxyInstance();
409
+ * const order: Order = {
410
+ * symbol: "MATIC-USD-MATIC",
411
+ * side: "BUY",
412
+ * type: "MARKET",
413
+ * quantity: 100,
414
+ * leverage: 2,
415
+ * executionTimestamp: Date.now()/1000,
416
+ * };
417
+ * // Get position risk conditional on this order being executed
418
+ * const posRisk = await mktData.positionRiskOnTrade("0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B", order, 0, 60);
419
+ * console.log(posRisk);
420
+ * }
421
+ * main();
422
+ */
423
+ async positionRiskOnTrade(traderAddr, order, signedPositionNotionalBaseCCY, tradingFeeTbps, indexPriceInfo, overrides) {
424
+ if (this.proxyContract == null || this.multicall == null) {
425
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
426
+ }
427
+ const isPredMkt = this.isPredictionMarket(order.symbol);
428
+ // fetch prices
429
+ if (indexPriceInfo == undefined) {
430
+ indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(order.symbol);
431
+ }
432
+ // signed trade amount
433
+ let tradeAmountBC = Math.abs(order.quantity) * (order.side == BUY_SIDE ? 1 : -1);
434
+ const symbol = order.symbol;
435
+ let obj = await this.dataForPositionRiskOnTrade(symbol, traderAddr, tradeAmountBC, indexPriceInfo, signedPositionNotionalBaseCCY, overrides);
436
+ const account = obj.account;
437
+ const maxLongTrade = obj.maxLongTrade;
438
+ const maxShortTrade = obj.maxShortTrade;
439
+ const ammPrice = obj.ammPrice;
440
+ let Sm = account.markPrice;
441
+ let S2 = indexPriceInfo.s2;
442
+ let S3 = account.collToQuoteConversion;
457
443
  // price for this order = amm price if no limit given, else conservatively adjusted
458
444
  let tradePrice;
459
445
  if (order.limitPrice == undefined) {
@@ -489,16 +475,6 @@ export default class MarketData extends PerpetualDataHandler {
489
475
  }
490
476
  }
491
477
  }
492
- // max buy
493
- const fMaxLong = this.proxyContract.interface.decodeFunctionResult("getMaxSignedOpenTradeSizeForPos", encodedResults[4].returnData)[0];
494
- const maxLongTrade = account.side == BUY_SIDE
495
- ? Math.max(0, ABK64x64ToFloat(fMaxLong) - (accountGiven ? 0 : account.positionNotionalBaseCCY))
496
- : ABK64x64ToFloat(fMaxLong) + account.positionNotionalBaseCCY;
497
- // max sell
498
- const fMaxShort = this.proxyContract.interface.decodeFunctionResult("getMaxSignedOpenTradeSizeForPos", encodedResults[5].returnData)[0];
499
- const maxShortTrade = account.side == SELL_SIDE
500
- ? Math.max(0, Math.abs(ABK64x64ToFloat(fMaxShort)) - (accountGiven ? 0 : Math.abs(account.positionNotionalBaseCCY)))
501
- : Math.abs(ABK64x64ToFloat(fMaxShort)) + Math.abs(account.positionNotionalBaseCCY);
502
478
  // Current state:
503
479
  let lotSizeBC = MarketData._getLotSize(order.symbol, this.symbolToPerpStaticInfo);
504
480
  // Too small, no change to account
@@ -520,10 +496,6 @@ export default class MarketData extends PerpetualDataHandler {
520
496
  newPositionBC = 0;
521
497
  }
522
498
  let newSide = newPositionBC > 0 ? BUY_SIDE : newPositionBC < 0 ? SELL_SIDE : CLOSED_SIDE;
523
- if (tradingFeeTbps === undefined) {
524
- // use usual input if not overriden
525
- tradingFeeTbps = Number(exchangeFeeTbps) + (order.brokerFeeTbps ?? 0);
526
- }
527
499
  let tradingFeeCC = (Math.abs(tradeAmountBC) * tradingFeeTbps * 1e-5 * S2) / S3;
528
500
  let referralFeeCC = this.symbolToPerpStaticInfo.get(account.symbol).referralRebate;
529
501
  // Trade type:
@@ -548,7 +520,7 @@ export default class MarketData extends PerpetualDataHandler {
548
520
  let initialMarginRate = this.symbolToPerpStaticInfo.get(account.symbol).initialMarginRate;
549
521
  targetLvg = isFlip || isOpen ? order.leverage ?? 1 / initialMarginRate : 0;
550
522
  let [b0, pos0] = isOpen ? [0, 0] : [account.collateralCC, currentPositionBC];
551
- traderDepositCC = getDepositAmountForLvgTrade(pos0, b0, tradeAmountBC, targetLvg, tradePrice, S3, Sm);
523
+ traderDepositCC = getDepositAmountForLvgTrade(pos0, b0, tradeAmountBC, targetLvg, tradePrice, S3, Sm, isPredMkt);
552
524
  // fees are paid from wallet in this case
553
525
  traderDepositCC += tradingFeeCC + referralFeeCC;
554
526
  }
@@ -573,7 +545,7 @@ export default class MarketData extends PerpetualDataHandler {
573
545
  ? Infinity
574
546
  : (Math.abs(newPositionBC) * Sm) / S3 / newMarginBalanceCC;
575
547
  // Liquidation params
576
- let [S2Liq, S3Liq, tau] = MarketData._getLiquidationParams(account.symbol, newLockedInValueQC, newPositionBC, newMarginCashCC, Sm, S3, this.symbolToPerpStaticInfo);
548
+ let [S2Liq, S3Liq, tau] = MarketData._getLiquidationParams(account.symbol, newLockedInValueQC, newPositionBC, newMarginCashCC, Sm, S3, S2, this.symbolToPerpStaticInfo);
577
549
  // New position risk
578
550
  let newPositionRisk = {
579
551
  symbol: account.symbol,
@@ -596,6 +568,18 @@ export default class MarketData extends PerpetualDataHandler {
596
568
  maxShortTrade: maxShortTrade,
597
569
  };
598
570
  }
571
+ /**
572
+ * Fee is relative to base-currency amount (=trade amount)
573
+ * @param state current perpetual state (need longBC and shortBC)
574
+ * @param maxMaintMgnRate maintenance margin rate param for pred mkts
575
+ * @param Sm Mark price
576
+ * @param tradeAmtBC signed trade amount
577
+ * @param tradeMgnRate margin rate param from perpetual
578
+ * @returns relative exchange fee in decimals
579
+ */
580
+ static exchangeFeePrdMkts(state, maxMaintMgnRate, Sm, tradeAmtBC, tradeMgnRate) {
581
+ return pmExchangeFee(Sm - 1, maxMaintMgnRate, state.shortBC, state.longBC, tradeAmtBC, tradeMgnRate);
582
+ }
599
583
  /**
600
584
  * Estimates what the position risk will be if given amount of collateral is added/removed from the account.
601
585
  * @param {number} deltaCollateral Amount of collateral to add or remove (signed)
@@ -625,11 +609,17 @@ export default class MarketData extends PerpetualDataHandler {
625
609
  throw new Error("not enough margin to remove");
626
610
  }
627
611
  if (indexPriceInfo == undefined) {
628
- let obj = await this.priceFeedGetter.fetchPricesForPerpetual(account.symbol);
629
- indexPriceInfo = [obj.idxPrices[0], obj.idxPrices[1], obj.mktClosed[0], obj.mktClosed[1]];
612
+ indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(account.symbol);
630
613
  }
631
614
  let perpetualState = await this.getPerpetualState(account.symbol, indexPriceInfo, overrides);
632
- let [S2, S3, Sm] = [perpetualState.indexPrice, perpetualState.collToQuoteIndexPrice, perpetualState.markPrice];
615
+ let Sm; //mark price
616
+ if (this.isPredictionMarket(account.symbol)) {
617
+ Sm = indexPriceInfo.ema + perpetualState.markPremium;
618
+ }
619
+ else {
620
+ Sm = perpetualState.indexPrice * (1 + perpetualState.markPremium);
621
+ }
622
+ let [S2, S3] = [perpetualState.indexPrice, perpetualState.collToQuoteIndexPrice];
633
623
  // no position: just increase collateral and kill liquidation vars
634
624
  if (account.positionNotionalBaseCCY == 0) {
635
625
  return {
@@ -669,7 +659,7 @@ export default class MarketData extends PerpetualDataHandler {
669
659
  }
670
660
  let newLeverage = (Math.abs(positionBC) * Sm) / S3 / newMarginBalanceCC;
671
661
  // Liquidation params
672
- let [S2Liq, S3Liq, tau] = MarketData._getLiquidationParams(account.symbol, lockedInQC, positionBC, newMarginCashCC, Sm, S3, this.symbolToPerpStaticInfo);
662
+ let [S2Liq, S3Liq, tau] = MarketData._getLiquidationParams(account.symbol, lockedInQC, positionBC, newMarginCashCC, Sm, S3, S2, this.symbolToPerpStaticInfo);
673
663
  // New position risk
674
664
  let newPositionRisk = {
675
665
  symbol: account.symbol,
@@ -688,35 +678,39 @@ export default class MarketData extends PerpetualDataHandler {
688
678
  return newPositionRisk;
689
679
  }
690
680
  /**
691
- * Calculates liquidation prices for a given position
681
+ * Calculates liquidation prices for a position
682
+ * constructed in positionRiskOnTrade/positionRiskOnCollateralAction
692
683
  * @param symbol Perpetual symbol
693
684
  * @param lockedInQC Locked in value
694
685
  * @param signedPositionBC Signed position size
695
- * @param marginCashCC Cash in margin account
686
+ * @param marginCashCC Available cash in margin account (includes unpaid funding)
696
687
  * @param markPrice Mark price
697
- * @param collToQuoteConversion Collateral index price
688
+ * @param collToQuoteConversion Collateral index price (S3)
689
+ * @param S2 index price
698
690
  * @param symbolToPerpStaticInfo Symbol-to-perp static info mapping
699
691
  * @returns [Base index price, Collateral index price, Maintenance margin rate]
700
692
  * @ignore
701
693
  */
702
- static _getLiquidationParams(symbol, lockedInQC, signedPositionBC, marginCashCC, markPrice, collToQuoteConversion, symbolToPerpStaticInfo) {
694
+ static _getLiquidationParams(symbol, lockedInQC, signedPositionBC, marginCashCC, markPrice, collToQuoteConversion, S2, symbolToPerpStaticInfo) {
703
695
  let S2Liq, S3Liq;
704
- let tau = symbolToPerpStaticInfo.get(symbol).maintenanceMarginRate;
705
- let ccyType = symbolToPerpStaticInfo.get(symbol).collateralCurrencyType;
706
- if (ccyType == CollaterlCCY.BASE) {
707
- S2Liq = calculateLiquidationPriceCollateralBase(lockedInQC, signedPositionBC, marginCashCC, tau);
708
- S3Liq = S2Liq;
709
- }
710
- else if (ccyType == CollaterlCCY.QUANTO) {
711
- S3Liq = collToQuoteConversion;
712
- S2Liq = calculateLiquidationPriceCollateralQuanto(lockedInQC, signedPositionBC, marginCashCC, tau, collToQuoteConversion, markPrice);
713
- }
714
- else {
715
- S2Liq = calculateLiquidationPriceCollateralQuote(lockedInQC, signedPositionBC, marginCashCC, tau);
716
- }
717
- // floor at 0
718
- S2Liq = S2Liq < 0 ? 0 : S2Liq;
719
- S3Liq = S3Liq && S3Liq < 0 ? 0 : S3Liq;
696
+ const staticInfo = symbolToPerpStaticInfo.get(symbol);
697
+ let tau = staticInfo.maintenanceMarginRate;
698
+ let ccyType = staticInfo.collateralCurrencyType;
699
+ const isPred = MarketData.isPredictionMarketStatic(staticInfo);
700
+ const idx_availableCashCC = 2;
701
+ const idx_cash = 3;
702
+ const idx_notional = 4;
703
+ const idx_locked_in = 5;
704
+ const idx_mark_price = 8;
705
+ const idx_s3 = 9;
706
+ let traderState = new Array(10);
707
+ traderState[idx_availableCashCC] = floatToABK64x64(marginCashCC);
708
+ traderState[idx_cash] = traderState[idx_availableCashCC];
709
+ traderState[idx_notional] = floatToABK64x64(signedPositionBC);
710
+ traderState[idx_locked_in] = floatToABK64x64(lockedInQC);
711
+ traderState[idx_mark_price] = floatToABK64x64(markPrice);
712
+ traderState[idx_s3] = floatToABK64x64(collToQuoteConversion);
713
+ [S2Liq, S3Liq, tau, ,] = MarketData._calculateLiquidationPrice(symbol, traderState, S2, symbolToPerpStaticInfo, isPred);
720
714
  return [S2Liq, S3Liq, tau];
721
715
  }
722
716
  /**
@@ -884,22 +878,28 @@ export default class MarketData extends PerpetualDataHandler {
884
878
  if (!this.proxyContract || !this.multicall) {
885
879
  throw new Error("proxy contract not initialized");
886
880
  }
881
+ if (this.isPredictionMarket(symbol)) {
882
+ // prediction markets
883
+ return this.pmMaxOrderSizeForTrader(traderAddr, symbol, overrides);
884
+ }
885
+ // regular markets
886
+ return this.rmMaxOrderSizeForTrader(traderAddr, symbol, overrides);
887
+ }
888
+ async pmMaxOrderSizeForTrader(traderAddr, symbol, overrides) {
889
+ if (!this.proxyContract || !this.multicall) {
890
+ throw new Error("proxy contract not initialized");
891
+ }
892
+ const IERC20 = new Interface(ERC20_ABI);
887
893
  const perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
888
- const poolId = this.getPoolIdFromSymbol(symbol);
889
894
  const poolInfo = this.poolStaticInfos[this.getPoolStaticInfoIndexFromSymbol(symbol)];
890
- const perpInfo = this.getPerpetualStaticInfo(symbol);
891
- const IERC20 = new Interface(ERC20_ABI);
892
- const indexPriceInfo = await this.priceFeedGetter
893
- .fetchPricesForPerpetual(symbol)
894
- .then((obj) => [obj.idxPrices[0], obj.idxPrices[1], obj.mktClosed[0], obj.mktClosed[1]]);
895
- const fS2S3 = [indexPriceInfo[0], indexPriceInfo[1]].map((x) => floatToABK64x64(x));
896
- let coll2SettlePromise = this.fetchCollateralToSettlementConversion(symbol);
895
+ const indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
896
+ const [fS2, fS3, fEma] = [indexPriceInfo.s2, indexPriceInfo.s3, indexPriceInfo.ema].map((x) => floatToABK64x64(x));
897
897
  const proxyCalls = [
898
898
  // 0: traderState
899
899
  {
900
900
  target: this.proxyContract.target,
901
901
  allowFailure: false,
902
- callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, fS2S3]),
902
+ callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, [fEma, fS3]]),
903
903
  },
904
904
  // 1: wallet balance
905
905
  {
@@ -907,31 +907,53 @@ export default class MarketData extends PerpetualDataHandler {
907
907
  allowFailure: false,
908
908
  callData: IERC20.encodeFunctionData("balanceOf", [traderAddr]),
909
909
  },
910
- // 2: exchange fee
910
+ // 2: amm state
911
911
  {
912
912
  target: this.proxyContract.target,
913
913
  allowFailure: false,
914
- callData: this.proxyContract.interface.encodeFunctionData("queryExchangeFee", [
915
- poolId,
916
- traderAddr,
917
- ZERO_ADDRESS,
918
- ]),
914
+ callData: this.proxyContract.interface.encodeFunctionData("getAMMState", [perpId, [fS2, fS3]]),
919
915
  },
920
916
  ];
921
917
  // multicall
922
918
  const encodedResults = await this.multicall.aggregate3.staticCall(proxyCalls, overrides || {});
923
- // position risk
924
- const idxNotional = 4;
925
919
  const traderState = this.proxyContract.interface.decodeFunctionResult("getTraderState", encodedResults[0].returnData)[0];
926
- const account = MarketData.buildMarginAccountFromState(symbol, traderState, this.symbolToPerpStaticInfo, [
927
- indexPriceInfo[0],
928
- indexPriceInfo[1],
929
- ]);
930
- // fee rate
931
- const feeRateTbps = this.proxyContract.interface.decodeFunctionResult("queryExchangeFee", encodedResults[2].returnData)[0];
932
- const feeRate = 1e-5 * Number(feeRateTbps);
933
- // Max based on margin requirements:
934
920
  const walletBalance = decNToFloat(IERC20.decodeFunctionResult("balanceOf", encodedResults[1].returnData)[0], poolInfo.poolSettleTokenDecimals);
921
+ const ammState = this.proxyContract.interface.decodeFunctionResult("getAMMState", encodedResults[2].returnData)[0];
922
+ const account = MarketData.buildMarginAccountFromState(symbol, traderState, this.symbolToPerpStaticInfo, indexPriceInfo, true //isPredMkt
923
+ );
924
+ const openInterestBC = ABK64x64ToFloat(ammState[11]);
925
+ const net = -ABK64x64ToFloat(ammState[1]);
926
+ let totLong, totShort;
927
+ if (net < 0) {
928
+ totLong = openInterestBC;
929
+ totShort = openInterestBC - Math.abs(net);
930
+ }
931
+ else {
932
+ totLong = openInterestBC - net;
933
+ totShort = openInterestBC;
934
+ }
935
+ let currentPositionBC = (account.side == BUY_SIDE ? 1 : -1) * account.positionNotionalBaseCCY;
936
+ const Sm = ABK64x64ToFloat(traderState[8]);
937
+ // settlement token must be equal to collateral token for walletBalance to be correct
938
+ const availCashCC = account.collateralCC + walletBalance + account.unrealizedFundingCollateralCCY;
939
+ const idxNotional = 4;
940
+ const [maxShortPosPerp, maxLongPosPerp] = await this.getMaxShortLongPos(perpId, traderState[idxNotional], overrides);
941
+ const maxShort = pmFindMaxTradeSize(-1, currentPositionBC, availCashCC, account.entryPrice * currentPositionBC, Sm, Sm, indexPriceInfo.s3, totLong, totShort, maxShortPosPerp, maxLongPosPerp);
942
+ const maxLong = pmFindMaxTradeSize(-1, currentPositionBC, availCashCC, account.entryPrice * currentPositionBC, Sm, Sm, indexPriceInfo.s3, totLong, totShort, maxShortPosPerp, maxLongPosPerp);
943
+ return { buy: maxLong, sell: maxShort };
944
+ }
945
+ /**
946
+ * Returns the maximal allowed short pos and long pos (signed) for a trader
947
+ * with given notional (in ABDK format) in the perpetual, ignoring the traders wallet balance
948
+ * @param perpId
949
+ * @param currentTraderPos ABDK64x64 notional position of trader
950
+ * @param overrides
951
+ * @returns [maxShortPos, maxLongPos] signed maximal position sizes
952
+ */
953
+ async getMaxShortLongPos(perpId, currentTraderPos, overrides) {
954
+ if (!this.proxyContract || !this.multicall) {
955
+ throw new Error("proxy contract not initialized");
956
+ }
935
957
  const proxyCalls2 = [
936
958
  // 0: max long
937
959
  {
@@ -939,7 +961,7 @@ export default class MarketData extends PerpetualDataHandler {
939
961
  allowFailure: false,
940
962
  callData: this.proxyContract.interface.encodeFunctionData("getMaxSignedOpenTradeSizeForPos", [
941
963
  perpId,
942
- traderState[idxNotional],
964
+ currentTraderPos,
943
965
  true,
944
966
  ]),
945
967
  },
@@ -949,7 +971,7 @@ export default class MarketData extends PerpetualDataHandler {
949
971
  allowFailure: false,
950
972
  callData: this.proxyContract.interface.encodeFunctionData("getMaxSignedOpenTradeSizeForPos", [
951
973
  perpId,
952
- traderState[idxNotional],
974
+ currentTraderPos,
953
975
  false,
954
976
  ]),
955
977
  },
@@ -959,15 +981,66 @@ export default class MarketData extends PerpetualDataHandler {
959
981
  // Max based on perp:
960
982
  // max buy
961
983
  const maxLongOrderPerp = ABK64x64ToFloat(this.proxyContract.interface.decodeFunctionResult("getMaxSignedOpenTradeSizeForPos", encodedResults2[0].returnData)[0]);
962
- const maxLongPosPerp = maxLongOrderPerp + ABK64x64ToFloat(traderState[idxNotional]);
984
+ const maxLongPosPerp = maxLongOrderPerp + ABK64x64ToFloat(currentTraderPos);
963
985
  // max short
964
986
  const maxShortOrderPerp = ABK64x64ToFloat(this.proxyContract.interface.decodeFunctionResult("getMaxSignedOpenTradeSizeForPos", encodedResults2[1].returnData)[0]);
965
- const maxShortPosPerp = maxShortOrderPerp + ABK64x64ToFloat(traderState[idxNotional]);
987
+ const maxShortPosPerp = maxShortOrderPerp + ABK64x64ToFloat(currentTraderPos);
988
+ return [maxShortPosPerp, maxLongPosPerp];
989
+ }
990
+ async rmMaxOrderSizeForTrader(traderAddr, symbol, overrides) {
991
+ const perpId = PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
992
+ const poolId = this.getPoolIdFromSymbol(symbol);
993
+ const poolInfo = this.poolStaticInfos[this.getPoolStaticInfoIndexFromSymbol(symbol)];
994
+ const perpInfo = this.getPerpetualStaticInfo(symbol);
995
+ const IERC20 = new Interface(ERC20_ABI);
996
+ const isPredMkt = false;
997
+ const indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
998
+ let coll2SettlePromise = this.fetchCollateralToSettlementConversion(symbol);
999
+ const [fS2, fS3, fEma] = [indexPriceInfo.s2, indexPriceInfo.s3, indexPriceInfo.ema].map((x) => floatToABK64x64(x));
1000
+ if (!this.proxyContract || !this.multicall) {
1001
+ throw new Error("proxy contract not initialized");
1002
+ }
1003
+ const proxyCalls = [
1004
+ // 0: traderState
1005
+ {
1006
+ target: this.proxyContract.target,
1007
+ allowFailure: false,
1008
+ callData: this.proxyContract.interface.encodeFunctionData("getTraderState", [perpId, traderAddr, [fEma, fS3]]),
1009
+ },
1010
+ // 1: wallet balance
1011
+ {
1012
+ target: poolInfo.poolSettleTokenAddr,
1013
+ allowFailure: false,
1014
+ callData: IERC20.encodeFunctionData("balanceOf", [traderAddr]),
1015
+ },
1016
+ // 2: exchange fee
1017
+ {
1018
+ target: this.proxyContract.target,
1019
+ allowFailure: false,
1020
+ callData: this.proxyContract.interface.encodeFunctionData("queryExchangeFee", [
1021
+ poolId,
1022
+ traderAddr,
1023
+ ZERO_ADDRESS,
1024
+ ]),
1025
+ },
1026
+ ];
1027
+ // multicall
1028
+ const encodedResults = await this.multicall.aggregate3.staticCall(proxyCalls, overrides || {});
1029
+ // position risk
1030
+ const idxNotional = 4;
1031
+ const traderState = this.proxyContract.interface.decodeFunctionResult("getTraderState", encodedResults[0].returnData)[0];
1032
+ const account = MarketData.buildMarginAccountFromState(symbol, traderState, this.symbolToPerpStaticInfo, indexPriceInfo, isPredMkt);
1033
+ // fee rate
1034
+ const feeRateTbps = this.proxyContract.interface.decodeFunctionResult("queryExchangeFee", encodedResults[2].returnData)[0];
1035
+ const feeRate = 1e-5 * Number(feeRateTbps);
1036
+ // Max based on margin requirements:
1037
+ const walletBalance = decNToFloat(IERC20.decodeFunctionResult("balanceOf", encodedResults[1].returnData)[0], poolInfo.poolSettleTokenDecimals);
1038
+ const [maxShortPosPerp, maxLongPosPerp] = await this.getMaxShortLongPos(perpId, traderState[idxNotional], overrides);
966
1039
  const curPos = (account.side == BUY_SIDE ? 1 : -1) * account.positionNotionalBaseCCY;
967
1040
  const px = await coll2SettlePromise;
968
1041
  const walletBalanceInMgnToken = walletBalance / px;
969
- const maxLongPosAccount = getMaxSignedPositionSize(account.collateralCC + walletBalanceInMgnToken + account.unrealizedFundingCollateralCCY, curPos, account.entryPrice * curPos, 1, account.markPrice, perpInfo.initialMarginRate, feeRate, account.markPrice, indexPriceInfo[0], account.collToQuoteConversion);
970
- const maxShortPosAccount = getMaxSignedPositionSize(account.collateralCC + walletBalanceInMgnToken + account.unrealizedFundingCollateralCCY, curPos, account.entryPrice * curPos, -1, account.markPrice, perpInfo.initialMarginRate, feeRate, account.markPrice, indexPriceInfo[0], account.collToQuoteConversion);
1042
+ const maxLongPosAccount = getMaxSignedPositionSize(account.collateralCC + walletBalanceInMgnToken + account.unrealizedFundingCollateralCCY, curPos, account.entryPrice * curPos, 1, account.markPrice, perpInfo.initialMarginRate, feeRate, account.markPrice, indexPriceInfo.s2, account.collToQuoteConversion);
1043
+ const maxShortPosAccount = getMaxSignedPositionSize(account.collateralCC + walletBalanceInMgnToken + account.unrealizedFundingCollateralCCY, curPos, account.entryPrice * curPos, -1, account.markPrice, perpInfo.initialMarginRate, feeRate, account.markPrice, indexPriceInfo.s2, account.collToQuoteConversion);
971
1044
  // max long/short all accounted for
972
1045
  const maxLong = Math.min(Math.abs(maxLongPosPerp), Math.abs(maxLongPosAccount));
973
1046
  const maxShort = Math.min(Math.abs(maxShortPosPerp), Math.abs(maxShortPosAccount));
@@ -1100,6 +1173,7 @@ export default class MarketData extends PerpetualDataHandler {
1100
1173
  /**
1101
1174
  * Get the current mark price
1102
1175
  * @param symbol symbol of the form ETH-USD-MATIC
1176
+ * @param indexPrices optional. IdxPriceInfo
1103
1177
  * @example
1104
1178
  * import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
1105
1179
  * async function main() {
@@ -1121,15 +1195,15 @@ export default class MarketData extends PerpetualDataHandler {
1121
1195
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1122
1196
  }
1123
1197
  if (indexPrices == undefined) {
1124
- let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1125
- indexPrices = [obj.idxPrices[0], obj.idxPrices[1]];
1198
+ indexPrices = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1126
1199
  }
1127
- return await PerpetualDataHandler._queryPerpetualMarkPrice(symbol, this.symbolToPerpStaticInfo, this.proxyContract, indexPrices);
1200
+ return await PerpetualDataHandler._queryPerpetualMarkPrice(symbol, this.symbolToPerpStaticInfo, this.proxyContract, indexPrices, this.isPredictionMarket(symbol));
1128
1201
  }
1129
1202
  /**
1130
1203
  * get the current price for a given quantity
1131
1204
  * @param symbol symbol of the form ETH-USD-MATIC
1132
1205
  * @param quantity quantity to be traded, negative if short
1206
+ * @param priceInfo [s2, s3, conf, params]; for non-prediction markets conf/params can be 0
1133
1207
  * @example
1134
1208
  * import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
1135
1209
  * async function main() {
@@ -1146,16 +1220,18 @@ export default class MarketData extends PerpetualDataHandler {
1146
1220
  *
1147
1221
  * @returns {number} price
1148
1222
  */
1149
- async getPerpetualPrice(symbol, quantity, indexPrices, overrides) {
1223
+ async getPerpetualPrice(symbol, quantity, priceInfo, overrides) {
1150
1224
  if (this.proxyContract == null) {
1151
1225
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1152
1226
  }
1153
- if (indexPrices == undefined) {
1227
+ if (priceInfo == undefined) {
1154
1228
  // fetch from API
1155
- let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1156
- indexPrices = [obj.idxPrices[0], obj.idxPrices[1]];
1229
+ priceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1157
1230
  }
1158
- return await PerpetualDataHandler._queryPerpetualPrice(symbol, quantity, this.symbolToPerpStaticInfo, this.proxyContract, indexPrices, overrides);
1231
+ return await PerpetualDataHandler._queryPerpetualPrice(symbol, quantity, this.symbolToPerpStaticInfo, this.proxyContract, [priceInfo.s2, priceInfo.s3], //s2,s3
1232
+ priceInfo.conf, //conf
1233
+ priceInfo.predMktCLOBParams, //params
1234
+ overrides);
1159
1235
  }
1160
1236
  /**
1161
1237
  * Query recent perpetual state from blockchain
@@ -1167,8 +1243,7 @@ export default class MarketData extends PerpetualDataHandler {
1167
1243
  throw Error("no proxy contract initialized. Use createProxyInstance().");
1168
1244
  }
1169
1245
  if (indexPriceInfo == undefined) {
1170
- let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1171
- indexPriceInfo = [obj.idxPrices[0], obj.idxPrices[1], obj.mktClosed[0], obj.mktClosed[1]];
1246
+ indexPriceInfo = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1172
1247
  }
1173
1248
  let state = await PerpetualDataHandler._queryPerpetualState(symbol, this.symbolToPerpStaticInfo, this.proxyContract, this.multicall, indexPriceInfo, overrides);
1174
1249
  return state;
@@ -1364,7 +1439,7 @@ export default class MarketData extends PerpetualDataHandler {
1364
1439
  * Result is in collateral currency
1365
1440
  * @param {string} traderAddr address of the trader
1366
1441
  * @param {string} symbol perpetual symbol of the form BTC-USD-MATIC
1367
- * @param indexPrices optional index prices, will otherwise fetch from REST API
1442
+ * @param indexPrices optional indexPriceInfo
1368
1443
  * @returns available margin in collateral currency
1369
1444
  * @example
1370
1445
  * import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
@@ -1386,11 +1461,10 @@ export default class MarketData extends PerpetualDataHandler {
1386
1461
  }
1387
1462
  if (indexPrices == undefined) {
1388
1463
  // fetch from API
1389
- let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1390
- indexPrices = [obj.idxPrices[0], obj.idxPrices[1]];
1464
+ indexPrices = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
1391
1465
  }
1392
1466
  let perpID = PerpetualDataHandler.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
1393
- let traderState = await this.proxyContract.getTraderState(perpID, traderAddr, indexPrices.map((x) => floatToABK64x64(x == undefined || Number.isNaN(x) ? 0 : x)), overrides || {});
1467
+ let traderState = await this.proxyContract.getTraderState(perpID, traderAddr, [indexPrices.s2, indexPrices.s3].map((x) => floatToABK64x64(x == undefined || Number.isNaN(x) ? 0 : x)), overrides || {});
1394
1468
  const idx_availableMargin = 1;
1395
1469
  let mgn = ABK64x64ToFloat(traderState[idx_availableMargin]);
1396
1470
  return mgn;
@@ -1657,7 +1731,7 @@ export default class MarketData extends PerpetualDataHandler {
1657
1731
  quoteCurrency: contractSymbolToSymbol(perp.S2QuoteCCY, _symbolList),
1658
1732
  indexPrice: 0,
1659
1733
  collToQuoteIndexPrice: 0,
1660
- markPrice: ABK64x64ToFloat(perp.currentMarkPremiumRate.fPrice),
1734
+ markPremium: ABK64x64ToFloat(perp.currentMarkPremiumRate.fPrice),
1661
1735
  midPrice: 0,
1662
1736
  currentFundingRateBps: 1e4 * ABK64x64ToFloat(perp.fCurrentFundingRate),
1663
1737
  openInterestBC: ABK64x64ToFloat(perp.fOpenInterest),
@@ -1706,7 +1780,6 @@ export default class MarketData extends PerpetualDataHandler {
1706
1780
  perp.isMarketClosed = perp.isMarketClosed || idxPriceS3Pair[1];
1707
1781
  }
1708
1782
  perp.indexPrice = idxPriceS2Pair[0];
1709
- perp.markPrice = idxPriceS2Pair[0] * (1 + perp.markPrice); // currently filled with mark premium rate
1710
1783
  let indexS3 = 1;
1711
1784
  if (info.collateralCurrencyType == COLLATERAL_CURRENCY_BASE) {
1712
1785
  indexS3 = idxPriceS2Pair[0];