@velocity-exchange/sdk 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/README.md +3 -3
  2. package/lib/browser/adminClient.d.ts +35 -0
  3. package/lib/browser/adminClient.js +65 -0
  4. package/lib/browser/config.js +6 -7
  5. package/lib/browser/constants/numericConstants.d.ts +1 -1
  6. package/lib/browser/constants/numericConstants.js +1 -1
  7. package/lib/browser/decode/user.js +5 -1
  8. package/lib/browser/idl/velocity.d.ts +146 -3
  9. package/lib/browser/idl/velocity.json +147 -4
  10. package/lib/browser/orderSubscriber/OrderSubscriber.js +3 -0
  11. package/lib/browser/pyth/pythLazerSubscriber.js +37 -27
  12. package/lib/browser/types.d.ts +4 -0
  13. package/lib/browser/user.d.ts +15 -0
  14. package/lib/browser/user.js +37 -1
  15. package/lib/browser/velocityClient.d.ts +46 -10
  16. package/lib/browser/velocityClient.js +107 -35
  17. package/lib/node/adminClient.d.ts +35 -0
  18. package/lib/node/adminClient.d.ts.map +1 -1
  19. package/lib/node/adminClient.js +65 -0
  20. package/lib/node/config.d.ts.map +1 -1
  21. package/lib/node/config.js +6 -7
  22. package/lib/node/constants/numericConstants.d.ts +1 -1
  23. package/lib/node/constants/numericConstants.d.ts.map +1 -1
  24. package/lib/node/constants/numericConstants.js +1 -1
  25. package/lib/node/decode/user.d.ts.map +1 -1
  26. package/lib/node/decode/user.js +5 -1
  27. package/lib/node/idl/velocity.d.ts +146 -3
  28. package/lib/node/idl/velocity.d.ts.map +1 -1
  29. package/lib/node/idl/velocity.json +147 -4
  30. package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
  31. package/lib/node/orderSubscriber/OrderSubscriber.js +3 -0
  32. package/lib/node/pyth/pythLazerSubscriber.d.ts.map +1 -1
  33. package/lib/node/pyth/pythLazerSubscriber.js +37 -27
  34. package/lib/node/types.d.ts +4 -0
  35. package/lib/node/types.d.ts.map +1 -1
  36. package/lib/node/user.d.ts +15 -0
  37. package/lib/node/user.d.ts.map +1 -1
  38. package/lib/node/user.js +37 -1
  39. package/lib/node/velocityClient.d.ts +46 -10
  40. package/lib/node/velocityClient.d.ts.map +1 -1
  41. package/lib/node/velocityClient.js +107 -35
  42. package/package.json +7 -3
  43. package/.prettierignore +0 -1
  44. package/CHANGELOG.md +0 -132
  45. package/build-browser.js +0 -58
  46. package/bunfig.toml +0 -3
  47. package/esbuild-shims.js +0 -12
  48. package/scripts/deposit-isolated-positions.ts +0 -110
  49. package/scripts/find-flagged-users.ts +0 -213
  50. package/scripts/grpc-client-test-comparison.ts +0 -372
  51. package/scripts/grpc-multiuser-client-test-comparison.ts +0 -158
  52. package/scripts/postbuild.js +0 -95
  53. package/scripts/single-grpc-client-test.ts +0 -284
  54. package/scripts/withdraw-isolated-positions.ts +0 -174
  55. package/src/accounts/README_WebSocketAccountSubscriberV2.md +0 -95
  56. package/src/accounts/README_WebSocketProgramAccountSubscriberV2.md +0 -135
  57. package/src/accounts/basicUserAccountSubscriber.ts +0 -79
  58. package/src/accounts/basicUserStatsAccountSubscriber.ts +0 -87
  59. package/src/accounts/bulkAccountLoader.ts +0 -358
  60. package/src/accounts/bulkUserStatsSubscription.ts +0 -40
  61. package/src/accounts/bulkUserSubscription.ts +0 -39
  62. package/src/accounts/customizedCadenceBulkAccountLoader.ts +0 -250
  63. package/src/accounts/fetch.ts +0 -200
  64. package/src/accounts/grpcAccountSubscriber.ts +0 -225
  65. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -73
  66. package/src/accounts/grpcMultiAccountSubscriber.ts +0 -566
  67. package/src/accounts/grpcMultiUserAccountSubscriber.ts +0 -328
  68. package/src/accounts/grpcProgramAccountSubscriber.ts +0 -264
  69. package/src/accounts/grpcUserAccountSubscriber.ts +0 -63
  70. package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -65
  71. package/src/accounts/grpcVelocityClientAccountSubscriber.ts +0 -257
  72. package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +0 -941
  73. package/src/accounts/laserProgramAccountSubscriber.ts +0 -266
  74. package/src/accounts/oneShotUserAccountSubscriber.ts +0 -88
  75. package/src/accounts/oneShotUserStatsAccountSubscriber.ts +0 -94
  76. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -223
  77. package/src/accounts/pollingOracleAccountSubscriber.ts +0 -151
  78. package/src/accounts/pollingTokenAccountSubscriber.ts +0 -147
  79. package/src/accounts/pollingUserAccountSubscriber.ts +0 -198
  80. package/src/accounts/pollingUserStatsAccountSubscriber.ts +0 -180
  81. package/src/accounts/pollingVelocityClientAccountSubscriber.ts +0 -774
  82. package/src/accounts/testBulkAccountLoader.ts +0 -59
  83. package/src/accounts/types.ts +0 -428
  84. package/src/accounts/utils.ts +0 -90
  85. package/src/accounts/webSocketAccountSubscriber.ts +0 -304
  86. package/src/accounts/webSocketAccountSubscriberV2.ts +0 -536
  87. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +0 -171
  88. package/src/accounts/webSocketProgramAccountSubscriber.ts +0 -244
  89. package/src/accounts/webSocketProgramAccountSubscriberV2.ts +0 -1048
  90. package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +0 -1042
  91. package/src/accounts/webSocketUserAccountSubscriber.ts +0 -139
  92. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +0 -131
  93. package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +0 -865
  94. package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +0 -897
  95. package/src/accounts/websocketProgramUserAccountSubscriber.ts +0 -127
  96. package/src/addresses/marketAddresses.ts +0 -28
  97. package/src/addresses/pda.ts +0 -620
  98. package/src/adminClient.ts +0 -8136
  99. package/src/assert/assert.ts +0 -5
  100. package/src/auctionSubscriber/auctionSubscriber.ts +0 -86
  101. package/src/auctionSubscriber/auctionSubscriberGrpc.ts +0 -99
  102. package/src/auctionSubscriber/index.ts +0 -9
  103. package/src/auctionSubscriber/types.ts +0 -30
  104. package/src/bankrun/bankrunConnection.ts +0 -630
  105. package/src/blockhashSubscriber/BlockhashSubscriber.ts +0 -160
  106. package/src/blockhashSubscriber/index.ts +0 -6
  107. package/src/blockhashSubscriber/types.ts +0 -13
  108. package/src/clock/clockSubscriber.ts +0 -146
  109. package/src/config.ts +0 -312
  110. package/src/constants/index.ts +0 -9
  111. package/src/constants/numericConstants.ts +0 -194
  112. package/src/constants/perpMarkets.ts +0 -127
  113. package/src/constants/spotMarkets.ts +0 -104
  114. package/src/constants/txConstants.ts +0 -2
  115. package/src/constituentMap/constituentMap.ts +0 -305
  116. package/src/constituentMap/pollingConstituentAccountSubscriber.ts +0 -99
  117. package/src/constituentMap/webSocketConstituentAccountSubscriber.ts +0 -121
  118. package/src/core/VelocityCore.ts +0 -606
  119. package/src/core/index.ts +0 -12
  120. package/src/core/instructions/deposit.ts +0 -64
  121. package/src/core/instructions/fill.ts +0 -51
  122. package/src/core/instructions/funding.ts +0 -33
  123. package/src/core/instructions/liquidation.ts +0 -55
  124. package/src/core/instructions/orders.ts +0 -84
  125. package/src/core/instructions/perpOrders.ts +0 -312
  126. package/src/core/instructions/settlement.ts +0 -40
  127. package/src/core/instructions/trigger.ts +0 -41
  128. package/src/core/instructions/withdraw.ts +0 -65
  129. package/src/core/remainingAccounts.ts +0 -320
  130. package/src/core/signedMsg.ts +0 -109
  131. package/src/decode/customCoder.ts +0 -148
  132. package/src/decode/user.ts +0 -401
  133. package/src/dlob/DLOB.ts +0 -2793
  134. package/src/dlob/DLOBNode.ts +0 -305
  135. package/src/dlob/DLOBSubscriber.ts +0 -269
  136. package/src/dlob/NodeList.ts +0 -244
  137. package/src/dlob/orderBookLevels.ts +0 -695
  138. package/src/dlob/types.ts +0 -37
  139. package/src/events/eventList.ts +0 -114
  140. package/src/events/eventSubscriber.ts +0 -521
  141. package/src/events/eventsServerLogProvider.ts +0 -189
  142. package/src/events/fetchLogs.ts +0 -219
  143. package/src/events/parse.ts +0 -271
  144. package/src/events/pollingLogProvider.ts +0 -113
  145. package/src/events/sort.ts +0 -51
  146. package/src/events/txEventCache.ts +0 -92
  147. package/src/events/types.ts +0 -337
  148. package/src/events/webSocketLogProvider.ts +0 -152
  149. package/src/factory/bigNum.ts +0 -709
  150. package/src/factory/oracleClient.ts +0 -73
  151. package/src/idl/pyth.json +0 -142
  152. package/src/idl/pyth.ts +0 -97
  153. package/src/idl/pyth_solana_receiver.json +0 -628
  154. package/src/idl/token_faucet.json +0 -229
  155. package/src/idl/token_faucet.ts +0 -197
  156. package/src/idl/velocity.json +0 -23974
  157. package/src/idl/velocity.ts +0 -23980
  158. package/src/index.ts +0 -150
  159. package/src/indicative-quotes/indicativeQuotesSender.ts +0 -233
  160. package/src/isomorphic/README.md +0 -19
  161. package/src/isomorphic/anchor.browser.ts +0 -44
  162. package/src/isomorphic/anchor.node.ts +0 -1
  163. package/src/isomorphic/anchor.ts +0 -1
  164. package/src/isomorphic/anchor29.browser.ts +0 -24
  165. package/src/isomorphic/anchor29.node.ts +0 -1
  166. package/src/isomorphic/anchor29.ts +0 -1
  167. package/src/isomorphic/grpc.browser.ts +0 -4
  168. package/src/isomorphic/grpc.node.ts +0 -130
  169. package/src/isomorphic/grpc.ts +0 -1
  170. package/src/jupiter/jupiterClient.ts +0 -502
  171. package/src/keypair.ts +0 -32
  172. package/src/margin/README.md +0 -138
  173. package/src/marginCalculation.ts +0 -407
  174. package/src/marinade/idl/idl.json +0 -1962
  175. package/src/marinade/index.ts +0 -73
  176. package/src/marinade/types.ts +0 -3925
  177. package/src/math/amm.ts +0 -1758
  178. package/src/math/auction.ts +0 -480
  179. package/src/math/bankruptcy.ts +0 -138
  180. package/src/math/builder.ts +0 -130
  181. package/src/math/conversion.ts +0 -45
  182. package/src/math/exchangeStatus.ts +0 -261
  183. package/src/math/funding.ts +0 -498
  184. package/src/math/insurance.ts +0 -171
  185. package/src/math/liquidation.ts +0 -433
  186. package/src/math/margin.ts +0 -327
  187. package/src/math/market.ts +0 -487
  188. package/src/math/oracles.ts +0 -477
  189. package/src/math/orders.ts +0 -500
  190. package/src/math/position.ts +0 -381
  191. package/src/math/repeg.ts +0 -223
  192. package/src/math/spotBalance.ts +0 -996
  193. package/src/math/spotMarket.ts +0 -115
  194. package/src/math/spotPosition.ts +0 -263
  195. package/src/math/state.ts +0 -71
  196. package/src/math/superStake.ts +0 -602
  197. package/src/math/tiers.ts +0 -73
  198. package/src/math/trade.ts +0 -879
  199. package/src/math/utils.ts +0 -183
  200. package/src/memcmp.ts +0 -279
  201. package/src/oracles/oracleClientCache.ts +0 -41
  202. package/src/oracles/oracleId.ts +0 -99
  203. package/src/oracles/prelaunchOracleClient.ts +0 -63
  204. package/src/oracles/pythClient.ts +0 -125
  205. package/src/oracles/pythLazerClient.ts +0 -141
  206. package/src/oracles/quoteAssetOracleClient.ts +0 -43
  207. package/src/oracles/strictOraclePrice.ts +0 -40
  208. package/src/oracles/types.ts +0 -82
  209. package/src/oracles/utils.ts +0 -45
  210. package/src/orderParams.ts +0 -117
  211. package/src/orderSubscriber/OrderSubscriber.ts +0 -378
  212. package/src/orderSubscriber/PollingSubscription.ts +0 -50
  213. package/src/orderSubscriber/WebsocketSubscription.ts +0 -137
  214. package/src/orderSubscriber/grpcSubscription.ts +0 -155
  215. package/src/orderSubscriber/index.ts +0 -7
  216. package/src/orderSubscriber/types.ts +0 -64
  217. package/src/priorityFee/averageOverSlotsStrategy.ts +0 -17
  218. package/src/priorityFee/averageStrategy.ts +0 -13
  219. package/src/priorityFee/ewmaStrategy.ts +0 -51
  220. package/src/priorityFee/heliusPriorityFeeMethod.ts +0 -68
  221. package/src/priorityFee/index.ts +0 -16
  222. package/src/priorityFee/maxOverSlotsStrategy.ts +0 -18
  223. package/src/priorityFee/maxStrategy.ts +0 -8
  224. package/src/priorityFee/priorityFeeSubscriber.ts +0 -328
  225. package/src/priorityFee/priorityFeeSubscriberMap.ts +0 -134
  226. package/src/priorityFee/solanaPriorityFeeMethod.ts +0 -46
  227. package/src/priorityFee/types.ts +0 -82
  228. package/src/priorityFee/velocityPriorityFeeMethod.ts +0 -53
  229. package/src/pyth/constants.ts +0 -9
  230. package/src/pyth/index.ts +0 -15
  231. package/src/pyth/pythLazerSubscriber.ts +0 -365
  232. package/src/pyth/types.ts +0 -4451
  233. package/src/pyth/utils.ts +0 -13
  234. package/src/slot/SlotSubscriber.ts +0 -126
  235. package/src/slot/SlothashSubscriber.ts +0 -163
  236. package/src/swap/UnifiedSwapClient.ts +0 -315
  237. package/src/swift/grpcSignedMsgUserAccountSubscriber.ts +0 -81
  238. package/src/swift/index.ts +0 -10
  239. package/src/swift/signedMsgUserAccountSubscriber.ts +0 -251
  240. package/src/swift/swiftOrderSubscriber.ts +0 -351
  241. package/src/testClient.ts +0 -42
  242. package/src/titan/titanClient.ts +0 -438
  243. package/src/token/index.ts +0 -13
  244. package/src/tokenFaucet.ts +0 -296
  245. package/src/tx/baseTxSender.ts +0 -651
  246. package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +0 -31
  247. package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +0 -105
  248. package/src/tx/blockhashFetcher/types.ts +0 -9
  249. package/src/tx/fastSingleTxSender.ts +0 -200
  250. package/src/tx/forwardOnlyTxSender.ts +0 -193
  251. package/src/tx/priorityFeeCalculator.ts +0 -117
  252. package/src/tx/reportTransactionError.ts +0 -176
  253. package/src/tx/retryTxSender.ts +0 -177
  254. package/src/tx/txHandler.ts +0 -1009
  255. package/src/tx/txParamProcessor.ts +0 -225
  256. package/src/tx/types.ts +0 -117
  257. package/src/tx/utils.ts +0 -133
  258. package/src/tx/whileValidTxSender.ts +0 -377
  259. package/src/types.ts +0 -2575
  260. package/src/user.ts +0 -5316
  261. package/src/userConfig.ts +0 -38
  262. package/src/userMap/PollingSubscription.ts +0 -61
  263. package/src/userMap/WebsocketSubscription.ts +0 -93
  264. package/src/userMap/grpcSubscription.ts +0 -93
  265. package/src/userMap/referrerMap.ts +0 -360
  266. package/src/userMap/revenueShareEscrowMap.ts +0 -342
  267. package/src/userMap/userMap.ts +0 -784
  268. package/src/userMap/userMapConfig.ts +0 -82
  269. package/src/userMap/userStatsMap.ts +0 -393
  270. package/src/userName.ts +0 -37
  271. package/src/userStats.ts +0 -159
  272. package/src/userStatsConfig.ts +0 -35
  273. package/src/util/TransactionConfirmationManager.ts +0 -333
  274. package/src/util/chainClock.ts +0 -65
  275. package/src/util/computeUnits.ts +0 -101
  276. package/src/util/digest.ts +0 -33
  277. package/src/util/ed25519Utils.ts +0 -95
  278. package/src/util/promiseTimeout.ts +0 -23
  279. package/src/velocityClient.ts +0 -14802
  280. package/src/velocityClientConfig.ts +0 -119
  281. package/src/wallet.ts +0 -91
  282. package/tests/VelocityCore/builder_escrow.test.ts +0 -121
  283. package/tests/VelocityCore/decode.test.ts +0 -16
  284. package/tests/VelocityCore/fill_trigger.test.ts +0 -73
  285. package/tests/VelocityCore/instructions.test.ts +0 -46
  286. package/tests/VelocityCore/pdas.test.ts +0 -30
  287. package/tests/VelocityCore/perp_orders.test.ts +0 -205
  288. package/tests/VelocityCore/remainingAccounts.test.ts +0 -72
  289. package/tests/VelocityCore/settlement_liquidation.test.ts +0 -69
  290. package/tests/accounts/customizedCadenceBulkAccountLoader.test.ts +0 -211
  291. package/tests/amm/test.ts +0 -2402
  292. package/tests/auctions/test.ts +0 -81
  293. package/tests/bn/test.ts +0 -355
  294. package/tests/builder/builderFee.test.ts +0 -42
  295. package/tests/ci/verifyConstants.ts +0 -393
  296. package/tests/decode/test.ts +0 -262
  297. package/tests/decode/userAccountBufferStrings.ts +0 -102
  298. package/tests/dlob/helpers.ts +0 -748
  299. package/tests/dlob/test.ts +0 -6969
  300. package/tests/dlob/tickSizeStandardization.ts +0 -545
  301. package/tests/events/parseLogsForCuUsage.ts +0 -139
  302. package/tests/exchangeStatus/test.ts +0 -45
  303. package/tests/insurance/test.ts +0 -40
  304. package/tests/liquidation/test.ts +0 -125
  305. package/tests/oracles/mmOracleGate.test.ts +0 -379
  306. package/tests/oracles/pythPegSnap.test.ts +0 -76
  307. package/tests/sdkParity/enumParity.test.ts +0 -84
  308. package/tests/sdkParity/marginCategoryFill.test.ts +0 -143
  309. package/tests/sdkParity/memcmpOffsets.test.ts +0 -139
  310. package/tests/spot/test.ts +0 -281
  311. package/tests/tx/TransactionConfirmationManager.test.ts +0 -312
  312. package/tests/tx/cachedBlockhashFetcher.test.ts +0 -96
  313. package/tests/tx/priorityFeeCalculator.ts +0 -77
  314. package/tests/tx/priorityFeeStrategy.ts +0 -95
  315. package/tests/user/bankruptcy.ts +0 -165
  316. package/tests/user/feeAndWithdrawLimits.ts +0 -284
  317. package/tests/user/getMarginCalculation.ts +0 -586
  318. package/tests/user/helpers.ts +0 -184
  319. package/tests/user/liquidations.ts +0 -129
  320. package/tests/user/marginCalculations.test.ts +0 -321
  321. package/tests/user/test.ts +0 -833
  322. package/tsconfig.browser.json +0 -18
  323. package/tsconfig.json +0 -36
package/tests/amm/test.ts DELETED
@@ -1,2402 +0,0 @@
1
- import {
2
- BN,
3
- PEG_PRECISION,
4
- PRICE_PRECISION,
5
- AMM_RESERVE_PRECISION,
6
- QUOTE_PRECISION,
7
- PERCENTAGE_PRECISION,
8
- calculateSpread,
9
- calculateSpreadBN,
10
- calculateSpreadFundingBiasScale,
11
- ZERO,
12
- sigNum,
13
- ONE,
14
- calculateLiveOracleStd,
15
- calculateLiveOracleTwap,
16
- calculateInventoryScale,
17
- calculateAllEstimatedFundingRate,
18
- calculateLongShortFundingRateAndLiveTwaps,
19
- getVammL2Generator,
20
- BASE_PRECISION,
21
- PerpMarketAccount,
22
- L2Level,
23
- calculateUpdatedAMM,
24
- calculateMarketOpenBidAsk,
25
- calculateSpreadReserves,
26
- calculatePrice,
27
- BID_ASK_SPREAD_PRECISION,
28
- squareRootBN,
29
- calculateReferencePriceOffset,
30
- calculateInventoryLiquidityRatio,
31
- ContractTier,
32
- isOracleValid,
33
- OracleGuardRails,
34
- getNewOracleConfPct,
35
- MMOraclePriceData,
36
- OraclePriceData,
37
- calculateAmmReservesAfterSwap,
38
- getSwapDirection,
39
- PositionDirection,
40
- // calculateReservePrice,
41
- } from '../../src';
42
- import { mockPerpMarkets } from '../dlob/helpers';
43
-
44
- import { assert } from '../../src/assert/assert';
45
- import * as _ from 'lodash';
46
-
47
- class AMMSpreadTerms {
48
- longVolSpread: number;
49
- shortVolSpread: number;
50
- longSpreadwPS: number;
51
- shortSpreadwPS: number;
52
- maxTargetSpread: number;
53
- inventorySpreadScale: number;
54
- longSpreadwInvScale: number;
55
- shortSpreadwInvScale: number;
56
- effectiveLeverage: number;
57
- effectiveLeverageCapped: number;
58
- longSpreadwEL: number;
59
- shortSpreadwEL: number;
60
- revenueRetreatAmount: number;
61
- halfRevenueRetreatAmount: number;
62
- longSpreadwRevRetreat: number;
63
- shortSpreadwRevRetreat: number;
64
- fundingBiasScale: number;
65
- longSpreadwFundingBias: number;
66
- shortSpreadwFundingBias: number;
67
- totalSpread: number;
68
- longSpread: number;
69
- shortSpread: number;
70
- }
71
-
72
- describe('AMM Tests', () => {
73
- it('Spread Maths', () => {
74
- let iscale = calculateInventoryScale(
75
- ZERO,
76
- AMM_RESERVE_PRECISION,
77
- AMM_RESERVE_PRECISION.div(new BN(2)),
78
- AMM_RESERVE_PRECISION.mul(new BN(3)).div(new BN(2)),
79
- 250,
80
- 30000
81
- );
82
- assert(iscale == 1);
83
-
84
- iscale = calculateInventoryScale(
85
- ONE,
86
- AMM_RESERVE_PRECISION,
87
- AMM_RESERVE_PRECISION.div(new BN(2)),
88
- AMM_RESERVE_PRECISION.mul(new BN(3)).div(new BN(2)),
89
- 250,
90
- 30000
91
- );
92
- assert(iscale == 1);
93
-
94
- let baa = new BN(1000);
95
- iscale = calculateInventoryScale(
96
- baa,
97
- AMM_RESERVE_PRECISION.add(baa),
98
- AMM_RESERVE_PRECISION.div(new BN(2)),
99
- AMM_RESERVE_PRECISION.mul(new BN(3)).div(new BN(2)),
100
- 250,
101
- 30000
102
- );
103
- console.log(iscale);
104
- assert(iscale == 1.00024);
105
-
106
- baa = new BN(100000);
107
- iscale = calculateInventoryScale(
108
- baa,
109
- AMM_RESERVE_PRECISION.add(baa),
110
- AMM_RESERVE_PRECISION.div(new BN(2)),
111
- AMM_RESERVE_PRECISION.mul(new BN(3)).div(new BN(2)),
112
- 250,
113
- 30000
114
- );
115
- console.log(iscale);
116
- assert(iscale == 1.024);
117
-
118
- baa = new BN(1000000);
119
- iscale = calculateInventoryScale(
120
- baa,
121
- AMM_RESERVE_PRECISION.add(baa),
122
- AMM_RESERVE_PRECISION.div(new BN(2)),
123
- AMM_RESERVE_PRECISION.mul(new BN(3)).div(new BN(2)),
124
- 250,
125
- 30000
126
- );
127
- console.log(iscale);
128
- assert(iscale == 1.24048);
129
-
130
- baa = new BN(10000000); // 2%
131
- iscale = calculateInventoryScale(
132
- baa,
133
- AMM_RESERVE_PRECISION.add(baa),
134
- AMM_RESERVE_PRECISION.div(new BN(2)),
135
- AMM_RESERVE_PRECISION.mul(new BN(3)).div(new BN(2)),
136
- 250,
137
- 30000
138
- );
139
- console.log(iscale);
140
- assert(iscale == 3.44896);
141
-
142
- baa = new BN(50000000); // 10%
143
- iscale = calculateInventoryScale(
144
- baa,
145
- AMM_RESERVE_PRECISION.add(baa),
146
- AMM_RESERVE_PRECISION.div(new BN(2)),
147
- AMM_RESERVE_PRECISION.mul(new BN(3)).div(new BN(2)),
148
- 250,
149
- 30000
150
- );
151
- console.log(iscale);
152
- assert(iscale == 14.33332);
153
-
154
- baa = AMM_RESERVE_PRECISION.div(new BN(4)); // 50%
155
- iscale = calculateInventoryScale(
156
- baa,
157
- AMM_RESERVE_PRECISION.add(baa),
158
- AMM_RESERVE_PRECISION.div(new BN(2)),
159
- AMM_RESERVE_PRECISION.mul(new BN(3)).div(new BN(2)),
160
- 250,
161
- 30000
162
- );
163
- console.log(iscale);
164
- assert(iscale == 120); //100%
165
-
166
- baa = AMM_RESERVE_PRECISION.div(new BN(4)); // 50%
167
- iscale = calculateInventoryScale(
168
- baa,
169
- AMM_RESERVE_PRECISION.add(baa),
170
- AMM_RESERVE_PRECISION.div(new BN(2)),
171
- AMM_RESERVE_PRECISION.mul(new BN(3)).div(new BN(2)),
172
- 250,
173
- 30000 * 2
174
- );
175
- console.log(iscale);
176
- assert(iscale == 120 * 2); //100%
177
-
178
- baa = AMM_RESERVE_PRECISION.div(new BN(5)); // <50%
179
- iscale = calculateInventoryScale(
180
- baa,
181
- AMM_RESERVE_PRECISION.add(baa),
182
- AMM_RESERVE_PRECISION.div(new BN(2)),
183
- AMM_RESERVE_PRECISION.mul(new BN(3)).div(new BN(2)),
184
- 250,
185
- 30000 * 2
186
- );
187
- assert(iscale == 160.99984);
188
-
189
- baa = new BN(855329058);
190
- iscale = calculateInventoryScale(
191
- baa,
192
- AMM_RESERVE_PRECISION.add(baa),
193
- AMM_RESERVE_PRECISION.div(new BN(2)),
194
- AMM_RESERVE_PRECISION,
195
- 250,
196
- 30000
197
- ); // >100%
198
- assert(iscale == 120);
199
- assert(250 * iscale == 30000);
200
-
201
- iscale = calculateInventoryScale(
202
- baa,
203
- AMM_RESERVE_PRECISION.add(baa), // ~85%
204
- AMM_RESERVE_PRECISION.div(new BN(2)),
205
- AMM_RESERVE_PRECISION.mul(new BN(3)).div(new BN(2)),
206
- 250,
207
- 30000
208
- );
209
- assert(iscale == 120);
210
- assert(250 * iscale == 30000);
211
-
212
- baa = new BN(-855329058); // ~85%
213
- iscale = calculateInventoryScale(
214
- baa,
215
- AMM_RESERVE_PRECISION.add(baa),
216
- AMM_RESERVE_PRECISION.div(new BN(2)),
217
- AMM_RESERVE_PRECISION.mul(new BN(3)).div(new BN(2)),
218
- 250,
219
- 30000
220
- );
221
- assert(iscale == 120);
222
- assert(250 * iscale == 30000);
223
-
224
- // 'bonk' scale
225
- iscale = calculateInventoryScale(
226
- new BN('30228000000000000'),
227
- new BN('2496788386034912600'),
228
- new BN('2443167585342470000'),
229
- new BN('2545411471321696000'),
230
- 3500,
231
- 100000
232
- );
233
- console.log(iscale);
234
- console.log((3500 * iscale) / 1e6);
235
- assert(iscale == 18.762285);
236
- assert((3500 * iscale) / 1e6 == 0.06566799749999999); //6.5%
237
- });
238
-
239
- it('Funding Bias Scale', () => {
240
- // values pinned to the program's calculate_spread_funding_bias_scale tests
241
- const twap = new BN(100).mul(PRICE_PRECISION); // $100
242
- // hourly rate matching the funding offset floor f_ref (~10.95%/yr):
243
- // fNorm = 1_250_000 * 1e6 / 1e8 * 24 = 300_000
244
- const saturatingRate = new BN(1_250_000);
245
- const qAmmLong = BASE_PRECISION.neg(); // users net short
246
- const qAmmShort = BASE_PRECISION; // users net long
247
- const one = BID_ASK_SPREAD_PRECISION.toNumber();
248
-
249
- // s = 0 disables
250
- assert(
251
- calculateSpreadFundingBiasScale(qAmmLong, saturatingRate, twap, 0) == one
252
- );
253
-
254
- // f * q >= 0: vAMM receives (or zero rate/inventory), β = 1
255
- assert(
256
- calculateSpreadFundingBiasScale(qAmmShort, saturatingRate, twap, 50) ==
257
- one
258
- );
259
- assert(
260
- calculateSpreadFundingBiasScale(
261
- qAmmLong,
262
- saturatingRate.neg(),
263
- twap,
264
- 50
265
- ) == one
266
- );
267
- assert(
268
- calculateSpreadFundingBiasScale(ZERO, saturatingRate, twap, 50) == one
269
- );
270
- assert(calculateSpreadFundingBiasScale(qAmmLong, ZERO, twap, 50) == one);
271
-
272
- // paying at f_ref: ρ ~= 1, β ~= 1 + s/100
273
- assert(
274
- calculateSpreadFundingBiasScale(qAmmLong, saturatingRate, twap, 50) ==
275
- 1_499_950
276
- );
277
- assert(
278
- calculateSpreadFundingBiasScale(
279
- qAmmShort,
280
- saturatingRate.neg(),
281
- twap,
282
- 50
283
- ) == 1_499_950
284
- );
285
-
286
- // half ramp: β = 1 + s/100 * 0.5
287
- assert(
288
- calculateSpreadFundingBiasScale(
289
- qAmmLong,
290
- saturatingRate.divn(2),
291
- twap,
292
- 50
293
- ) == 1_249_975
294
- );
295
-
296
- // past f_ref the ramp clamps at 1: β = 1 + s/100 exactly
297
- assert(
298
- calculateSpreadFundingBiasScale(
299
- qAmmLong,
300
- saturatingRate.muln(10),
301
- twap,
302
- 100
303
- ) ==
304
- 2 * one
305
- );
306
-
307
- // integration: paying side doubles at s = 100, other side untouched,
308
- // mirrors the program's calculate_spread_funding_bias_tests
309
- const calc = (rate: BN, s: number) =>
310
- calculateSpreadBN(
311
- 1000, // baseSpread
312
- ZERO,
313
- ZERO,
314
- 2000, // maxSpread
315
- AMM_RESERVE_PRECISION.muln(10),
316
- AMM_RESERVE_PRECISION.muln(10),
317
- new BN(34000000),
318
- new BN(-1000), // tiny vAMM-long inventory so σ = λ = 1
319
- new BN(34562304),
320
- QUOTE_PRECISION.muln(10),
321
- ZERO,
322
- AMM_RESERVE_PRECISION.muln(10),
323
- ZERO,
324
- AMM_RESERVE_PRECISION.muln(100000),
325
- ZERO,
326
- ZERO,
327
- ZERO,
328
- ZERO,
329
- ZERO,
330
- 0,
331
- rate,
332
- twap,
333
- s
334
- ) as [number, number];
335
-
336
- const [long0, short0] = calc(saturatingRate.muln(10), 0);
337
- assert(long0 == 500);
338
- assert(short0 == 500);
339
-
340
- const [long1, short1] = calc(saturatingRate.muln(10), 100);
341
- assert(long1 == long0);
342
- assert(short1 == short0 * 2);
343
-
344
- const [long2, short2] = calc(saturatingRate.muln(10).neg(), 100);
345
- assert(long2 == long0);
346
- assert(short2 == short0);
347
- });
348
-
349
- it('Various Spreads', () => {
350
- const baseSpread: number = 0.025 * 1e6;
351
- const lastOracleReservePriceSpreadPct: BN = ZERO;
352
- const lastOracleConfPct: BN = ZERO;
353
- const maxSpread: number = 0.03 * 1e6;
354
- const quoteAssetReserve: BN = new BN(
355
- AMM_RESERVE_PRECISION.toNumber() * 100
356
- );
357
- const terminalQuoteAssetReserve: BN = new BN(
358
- AMM_RESERVE_PRECISION.toNumber() * 100
359
- );
360
- const pegMultiplier: BN = new BN(13.455 * PEG_PRECISION.toNumber());
361
- const baseAssetAmountWithAmm: BN = ZERO;
362
- const reservePrice: BN = new BN(13.455 * PRICE_PRECISION.toNumber());
363
- const totalFeeMinusDistributions: BN = new BN(1);
364
- const netRevenueSinceLastFunding: BN = new BN(
365
- QUOTE_PRECISION.toNumber() * 2
366
- );
367
- const baseAssetReserve: BN = new BN(AMM_RESERVE_PRECISION.toNumber() * 100);
368
- const minBaseAssetReserve: BN = new BN(
369
- AMM_RESERVE_PRECISION.toNumber() * 90
370
- );
371
- const maxBaseAssetReserve: BN = new BN(
372
- AMM_RESERVE_PRECISION.toNumber() * 110
373
- );
374
- const markStd: BN = new BN(0.45 * PRICE_PRECISION.toNumber());
375
- const oracleStd: BN = new BN(0.55 * PRICE_PRECISION.toNumber());
376
- const longIntensity: BN = new BN(QUOTE_PRECISION.toNumber() * 20);
377
- const shortIntensity: BN = new BN(QUOTE_PRECISION.toNumber() * 2);
378
- const volume24H: BN = new BN(QUOTE_PRECISION.toNumber() * 25);
379
-
380
- const spreads = calculateSpreadBN(
381
- baseSpread,
382
- lastOracleReservePriceSpreadPct,
383
- lastOracleConfPct,
384
- maxSpread,
385
- quoteAssetReserve,
386
- terminalQuoteAssetReserve,
387
- pegMultiplier,
388
- baseAssetAmountWithAmm,
389
- reservePrice,
390
- totalFeeMinusDistributions,
391
- netRevenueSinceLastFunding,
392
- baseAssetReserve,
393
- minBaseAssetReserve,
394
- maxBaseAssetReserve,
395
- markStd,
396
- oracleStd,
397
- longIntensity,
398
- shortIntensity,
399
- volume24H,
400
- 0
401
- );
402
- const l1 = spreads[0];
403
- const s1 = spreads[1];
404
-
405
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
406
- // @ts-ignore
407
- const terms1: AMMSpreadTerms = calculateSpreadBN(
408
- baseSpread,
409
- lastOracleReservePriceSpreadPct,
410
- lastOracleConfPct,
411
- maxSpread,
412
- quoteAssetReserve,
413
- terminalQuoteAssetReserve,
414
- pegMultiplier,
415
- baseAssetAmountWithAmm,
416
- reservePrice,
417
- totalFeeMinusDistributions,
418
- netRevenueSinceLastFunding,
419
- baseAssetReserve,
420
- minBaseAssetReserve,
421
- maxBaseAssetReserve,
422
- markStd,
423
- oracleStd,
424
- longIntensity,
425
- shortIntensity,
426
- volume24H,
427
- 0,
428
- ZERO,
429
- ZERO,
430
- 0,
431
- true
432
- );
433
- // console.log(terms1);
434
-
435
- console.log('long/short spread:', l1, s1);
436
- assert(l1 == 12500);
437
- assert(s1 == 12500);
438
- assert(l1 == terms1.longSpread);
439
- assert(s1 == terms1.shortSpread);
440
-
441
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
442
- // @ts-ignore
443
- const terms2: AMMSpreadTerms = calculateSpreadBN(
444
- 300,
445
- new BN(0),
446
- new BN(484),
447
- 47500,
448
- new BN(923807816209694),
449
- new BN(925117623772584),
450
- new BN(13731157),
451
- new BN(-1314027016625),
452
- new BN(13667686),
453
- new BN(115876379475),
454
- new BN(91316628),
455
- new BN(928097825691666),
456
- new BN(907979542352912),
457
- new BN(945977491145601),
458
- new BN(161188), // mark std
459
- new BN(145963), // oracle std
460
- new BN(12358265776),
461
- new BN(72230366233),
462
- new BN(432067603632),
463
- 0,
464
- ZERO,
465
- ZERO,
466
- 0,
467
- true
468
- );
469
-
470
- assert(terms2.effectiveLeverageCapped >= 1.0002);
471
- assert(terms2.inventorySpreadScale == 8.443219);
472
- assert(terms2.longSpread == 150);
473
- assert(terms2.shortSpread == 3960);
474
-
475
- // add spread offset
476
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
477
- // @ts-ignore
478
- const terms3: AMMSpreadTerms = calculateSpreadBN(
479
- 300,
480
- new BN(0),
481
- new BN(484),
482
- 47500,
483
- new BN(923807816209694),
484
- new BN(925117623772584),
485
- new BN(13731157),
486
- new BN(-1314027016625),
487
- new BN(13667686),
488
- new BN(115876379475),
489
- new BN(91316628),
490
- new BN(928097825691666),
491
- new BN(907979542352912),
492
- new BN(945977491145601),
493
- new BN(161188),
494
- new BN(145963), // oracle std
495
- new BN(12358265776),
496
- new BN(72230366233),
497
- new BN(432067603632),
498
- 0,
499
- ZERO,
500
- ZERO,
501
- 0,
502
- true
503
- );
504
-
505
- // console.log(terms3);
506
- assert(terms3.effectiveLeverageCapped >= 1.0002);
507
- assert(terms3.inventorySpreadScale == 8.443219);
508
- assert(terms3.longSpread == 150);
509
- assert(terms3.shortSpread == 3960);
510
- assert(terms3.longSpread + terms3.shortSpread == 3960 + 150);
511
-
512
- // add spread offset
513
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
514
- // @ts-ignore
515
- const terms4: AMMSpreadTerms = calculateSpreadBN(
516
- 300,
517
- new BN(0),
518
- new BN(484),
519
- 47500,
520
- new BN(923807816209694),
521
- new BN(925117623772584),
522
- new BN(13731157),
523
- new BN(-1314027016625),
524
- new BN(13667686),
525
- new BN(115876379475),
526
- new BN(91316628),
527
- new BN(928097825691666),
528
- new BN(907979542352912),
529
- new BN(945977491145601),
530
- new BN(161188),
531
- new BN(1459632439), // oracle std (unchanged)
532
- new BN(12358265776),
533
- new BN(72230366233),
534
- new BN(432067603632),
535
- 0,
536
- ZERO,
537
- ZERO,
538
- 0,
539
- true
540
- );
541
-
542
- assert(terms4.effectiveLeverageCapped >= 1.0002);
543
- assert(terms4.inventorySpreadScale == 1.73492);
544
- assert(terms4.longSpread == 89746);
545
- assert(terms4.shortSpread == 910254);
546
- assert(terms4.longSpread + terms4.shortSpread == 1000000);
547
- });
548
-
549
- it('Corner Case Spreads', () => {
550
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
551
- // @ts-ignore
552
- const terms2: AMMSpreadTerms = calculateSpreadBN(
553
- 1000,
554
- new BN(5555),
555
- new BN(1131),
556
- 20000,
557
- new BN(1009967115003047),
558
- new BN(1009811402660255),
559
- new BN(13460124),
560
- new BN(15328930153),
561
- new BN(13667686),
562
- new BN(1235066973),
563
- new BN(88540713),
564
- new BN(994097717724176),
565
- new BN(974077854655784),
566
- new BN(1014841945381208),
567
- new BN(103320),
568
- new BN(59975),
569
- new BN(768323534),
570
- new BN(243875031),
571
- new BN(130017761029),
572
- 0,
573
- ZERO,
574
- ZERO,
575
- 0,
576
- true
577
- );
578
-
579
- assert(terms2.effectiveLeverageCapped <= 1.000001);
580
- assert(terms2.inventorySpreadScale == 1.0306);
581
- assert(terms2.longSpread == 515);
582
- assert(terms2.shortSpread == 5611);
583
-
584
- const suiExample = {
585
- status: 'active',
586
- contractType: 'perpetual',
587
- contractTier: 'c',
588
- expiryTs: '0',
589
- expiryPrice: '0',
590
- marketIndex: 9,
591
- pubkey: '91NsaUmTNNdLGbYtwmoiYSn9SgWHCsZiChfMYMYZ2nQx',
592
- name: 'SUI-PERP',
593
- amm: {
594
- baseAssetReserve: '234381482764434',
595
- sqrtK: '109260723000000001',
596
- lastFundingRate: '-16416',
597
- lastFundingRateTs: '1705845755',
598
- lastMarkPriceTwap: '1105972',
599
- lastMarkPriceTwap5Min: '1101202',
600
- lastMarkPriceTwapTs: '1705846920',
601
- lastTradeTs: '1705846920',
602
- oracle: '3Qub3HaAJaa2xNY7SUqPKd3vVwTqDfDDkEUMPjXD2c1q',
603
- oracleSource: 'pyth',
604
- historicalOracleData: {
605
- lastOraclePrice: '1099778',
606
- lastOracleDelay: '2',
607
- lastOracleConf: '0',
608
- lastOraclePriceTwap: '1106680',
609
- lastOraclePriceTwap5Min: '1102634',
610
- lastOraclePriceTwapTs: '1705846920',
611
- },
612
- lastOracleReservePriceSpreadPct: '-262785',
613
- lastOracleConfPct: '1359',
614
- fundingPeriod: '3600',
615
- quoteAssetReserve: '50933655038273508156',
616
- pegMultiplier: '4',
617
- cumulativeFundingRateLong: '186069301',
618
- cumulativeFundingRateShort: '186007157',
619
- last24HAvgFundingRate: '35147',
620
- lastFundingRateShort: '-16416',
621
- lastFundingRateLong: '-16416',
622
- totalLiquidationFee: '4889264000',
623
- totalFeeMinusDistributions: '-29523583393',
624
- totalFeeWithdrawn: '5251194706',
625
- totalFee: '7896066035',
626
- totalFeeEarnedPerLp: '77063238',
627
- orderStepSize: '1000000000',
628
- orderTickSize: '100',
629
- maxFillReserveFraction: '100',
630
- maxSlippageRatio: '50',
631
- baseSpread: '5000',
632
- curveUpdateIntensity: '100',
633
- baseAssetAmountWithAmm: '306519581',
634
- baseAssetAmountLong: '223405000000000',
635
- baseAssetAmountShort: '-224167000000000',
636
- quoteAssetAmount: '57945607973',
637
- terminalQuoteAssetReserve: '50933588428309274920',
638
- concentrationCoef: '1207100',
639
- feePool: '[object Object]',
640
- totalExchangeFee: '10110336057',
641
- totalMmFee: '-1870961568',
642
- netRevenueSinceLastFunding: '-141830281',
643
- lastUpdateSlot: '243204071',
644
- lastOracleNormalisedPrice: '1098594',
645
- lastOracleValid: 'true',
646
- lastBidPriceTwap: '1105864',
647
- lastAskPriceTwap: '1106081',
648
- longSpread: '259471',
649
- shortSpread: '3314',
650
- maxSpread: '29500',
651
- ammJitIntensity: '200',
652
- maxOpenInterest: '2000000000000000',
653
- maxBaseAssetReserve: '282922257844734',
654
- minBaseAssetReserve: '194169322578092',
655
- totalSocialLoss: '0',
656
- quoteBreakEvenAmountLong: '-237442196125',
657
- quoteBreakEvenAmountShort: '243508341566',
658
- quoteEntryAmountLong: '-234074123777',
659
- quoteEntryAmountShort: '240215285058',
660
- markStd: '237945',
661
- oracleStd: '8086',
662
- longIntensityCount: '0',
663
- longIntensityVolume: '162204',
664
- shortIntensityCount: '995',
665
- shortIntensityVolume: '2797331131',
666
- volume24H: '91370028405',
667
- minOrderSize: '1000000000',
668
- maxPositionSize: '0',
669
- bidBaseAssetReserve: '234770820775670',
670
- bidQuoteAssetReserve: '50849187948657797529',
671
- askBaseAssetReserve: '205083797418879',
672
- askQuoteAssetReserve: '58209891472312580749',
673
- },
674
- numberOfUsersWithBase: '279',
675
- numberOfUsers: '436',
676
- marginRatioInitial: '1000',
677
- marginRatioMaintenance: '500',
678
- nextFillRecordId: '69433',
679
- nextFundingRateRecordId: '6221',
680
- nextCurveRecordId: '1731',
681
- pnlPool: {
682
- scaledBalance: '61514197782399',
683
- marketIndex: '0',
684
- },
685
- liquidatorFee: '10000',
686
- ifLiquidationFee: '20000',
687
- imfFactor: '450',
688
- unrealizedPnlImfFactor: '450',
689
- unrealizedPnlMaxImbalance: '200000000',
690
- unrealizedPnlInitialAssetWeight: '0',
691
- unrealizedPnlMaintenanceAssetWeight: '10000',
692
- insuranceClaim: {
693
- revenueWithdrawSinceLastSettle: '100000000',
694
- maxRevenueWithdrawPerPeriod: '100000000',
695
- lastRevenueWithdrawTs: '1705846454',
696
- quoteSettledInsurance: '164388488',
697
- quoteMaxInsurance: '1000000000',
698
- },
699
- quoteSpotMarketIndex: '0',
700
- feeAdjustment: '0',
701
- };
702
-
703
- const reservePrice = calculatePrice(
704
- new BN(suiExample.amm.baseAssetReserve),
705
- new BN(suiExample.amm.quoteAssetReserve),
706
- new BN(suiExample.amm.pegMultiplier)
707
- );
708
- console.log('reservePrice', reservePrice.toString());
709
- assert(reservePrice.eq(new BN('869243')));
710
-
711
- const reservePriceMod = calculatePrice(
712
- new BN(suiExample.amm.baseAssetReserve),
713
- new BN(suiExample.amm.quoteAssetReserve),
714
- new BN(suiExample.amm.pegMultiplier).add(ONE)
715
- );
716
- console.log('reservePriceMod', reservePriceMod.toString());
717
- assert(reservePriceMod.eq(new BN('1086554')));
718
-
719
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
720
- // @ts-ignore
721
- const termsSuiExample: AMMSpreadTerms = calculateSpreadBN(
722
- Number(suiExample.amm.baseSpread.toString()),
723
- new BN(suiExample.amm.lastOracleReservePriceSpreadPct),
724
- new BN(suiExample.amm.lastOracleConfPct),
725
- Number(suiExample.amm.maxSpread.toString()),
726
- new BN(suiExample.amm.quoteAssetReserve),
727
- new BN(suiExample.amm.terminalQuoteAssetReserve),
728
- new BN(suiExample.amm.pegMultiplier),
729
- new BN(suiExample.amm.baseAssetAmountWithAmm),
730
- reservePrice, // reserve price
731
- new BN(suiExample.amm.totalFeeMinusDistributions),
732
- new BN(suiExample.amm.netRevenueSinceLastFunding),
733
- new BN(suiExample.amm.baseAssetReserve),
734
- new BN(suiExample.amm.minBaseAssetReserve),
735
- new BN(suiExample.amm.maxBaseAssetReserve),
736
- new BN(suiExample.amm.markStd),
737
- new BN(suiExample.amm.oracleStd),
738
- new BN(suiExample.amm.longIntensityVolume),
739
- new BN(suiExample.amm.shortIntensityVolume),
740
- new BN(suiExample.amm.volume24H),
741
- 0,
742
- ZERO,
743
- ZERO,
744
- 0,
745
- true
746
- );
747
-
748
- assert(termsSuiExample.effectiveLeverageCapped <= 1.000001);
749
- assert(termsSuiExample.inventorySpreadScale == 1.00007);
750
- assert(
751
- termsSuiExample.longSpread == 269813,
752
- `SUI long spread got ${termsSuiExample.longSpread}`
753
- );
754
- assert(
755
- termsSuiExample.shortSpread == 3925,
756
- `SUI short spread got ${termsSuiExample.shortSpread}`
757
- );
758
-
759
- // reset amm reserves/peg to balanced values s.t. liquidity/price is the same
760
- // to avoid error prone int math
761
-
762
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
763
- // @ts-ignore
764
- const termsSuiExampleMod1: AMMSpreadTerms = calculateSpreadBN(
765
- Number(suiExample.amm.baseSpread.toString()),
766
- ZERO,
767
- new BN(suiExample.amm.lastOracleConfPct),
768
- Number(suiExample.amm.maxSpread.toString()),
769
- new BN(suiExample.amm.quoteAssetReserve),
770
- new BN(suiExample.amm.terminalQuoteAssetReserve),
771
- new BN(suiExample.amm.pegMultiplier),
772
- new BN(suiExample.amm.baseAssetAmountWithAmm),
773
- reservePriceMod, // reserve price
774
- new BN(suiExample.amm.totalFeeMinusDistributions),
775
- new BN(suiExample.amm.netRevenueSinceLastFunding),
776
- new BN(suiExample.amm.baseAssetReserve),
777
- new BN(suiExample.amm.minBaseAssetReserve),
778
- new BN(suiExample.amm.maxBaseAssetReserve),
779
- new BN(suiExample.amm.markStd),
780
- new BN(suiExample.amm.oracleStd),
781
- new BN(suiExample.amm.longIntensityVolume),
782
- new BN(suiExample.amm.shortIntensityVolume),
783
- new BN(suiExample.amm.volume24H),
784
- 0,
785
- ZERO,
786
- ZERO,
787
- 0,
788
- true
789
- );
790
- console.log(termsSuiExampleMod1);
791
-
792
- // todo: add sdk recenter function?
793
-
794
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
795
- // @ts-ignore
796
- const termsSuiExampleMod2: AMMSpreadTerms = calculateSpreadBN(
797
- Number(suiExample.amm.baseSpread.toString()),
798
- ZERO,
799
- new BN(suiExample.amm.lastOracleConfPct),
800
- Number(suiExample.amm.maxSpread.toString()),
801
- new BN(suiExample.amm.sqrtK),
802
- new BN(suiExample.amm.terminalQuoteAssetReserve),
803
- reservePriceMod, // peg
804
- new BN(suiExample.amm.baseAssetAmountWithAmm),
805
- reservePriceMod, // reserve price
806
- new BN(suiExample.amm.totalFeeMinusDistributions),
807
- new BN(suiExample.amm.netRevenueSinceLastFunding),
808
- new BN(suiExample.amm.sqrtK),
809
- new BN(suiExample.amm.sqrtK),
810
- new BN(suiExample.amm.maxBaseAssetReserve),
811
- new BN(suiExample.amm.markStd),
812
- new BN(suiExample.amm.oracleStd),
813
- new BN(suiExample.amm.longIntensityVolume),
814
- new BN(suiExample.amm.shortIntensityVolume),
815
- new BN(suiExample.amm.volume24H),
816
- 0,
817
- ZERO,
818
- ZERO,
819
- 0,
820
- true
821
- );
822
-
823
- console.log(termsSuiExampleMod2);
824
- assert(
825
- _.isEqual(
826
- termsSuiExampleMod2.maxTargetSpread,
827
- termsSuiExampleMod1.maxTargetSpread
828
- )
829
- );
830
- assert(
831
- _.isEqual(
832
- termsSuiExampleMod2.shortSpreadwPS,
833
- termsSuiExampleMod1.shortSpreadwPS
834
- )
835
- );
836
- assert(
837
- _.isEqual(
838
- termsSuiExampleMod2.longSpreadwPS,
839
- termsSuiExampleMod1.longSpreadwPS
840
- )
841
- );
842
-
843
- // note: effectiveLeverage as currently implemented is sensitive to peg change
844
- });
845
-
846
- it('Spread Reserves (with offset)', () => {
847
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
848
- const mockMarket1 = myMockPerpMarkets[0];
849
- const mockAmm = mockMarket1.amm;
850
- const mockMarketStats = mockMarket1.marketStats;
851
- const now = new BN(new Date().getTime() / 1000); //todo
852
-
853
- const oraclePriceData = {
854
- price: new BN(13.553 * PRICE_PRECISION.toNumber()),
855
- slot: new BN(68 + 1),
856
- confidence: new BN(1),
857
- hasSufficientNumberOfDataPoints: true,
858
- isMMOracleActive: true,
859
- } as MMOraclePriceData;
860
-
861
- const reserves = calculateSpreadReserves(
862
- mockAmm,
863
- mockMarketStats,
864
- oraclePriceData,
865
- now
866
- );
867
- assert(reserves[0].baseAssetReserve.eq(new BN('1000000000')));
868
- assert(reserves[0].quoteAssetReserve.eq(new BN('12000000000')));
869
- assert(reserves[1].baseAssetReserve.eq(new BN('1000000000')));
870
- assert(reserves[1].quoteAssetReserve.eq(new BN('12000000000')));
871
-
872
- mockAmm.baseAssetReserve = new BN(1000000000);
873
- mockAmm.quoteAssetReserve = new BN(1000000000);
874
- mockAmm.sqrtK = new BN(1000000000);
875
-
876
- mockAmm.baseAssetAmountWithAmm = new BN(0);
877
- mockAmm.pegMultiplier = new BN(13.553 * PEG_PRECISION.toNumber());
878
- mockAmm.ammJitIntensity = 200;
879
- mockAmm.curveUpdateIntensity = 200;
880
- mockAmm.baseSpread = 2500;
881
- mockAmm.maxSpread = 25000;
882
-
883
- mockMarketStats.last24HAvgFundingRate = new BN(7590328523);
884
-
885
- mockMarketStats.lastMarkPriceTwap = new BN(
886
- (oraclePriceData.price.toNumber() / 1e6 - 0.01) * 1e6
887
- );
888
- mockMarketStats.historicalOracleData.lastOraclePriceTwap = new BN(
889
- (oraclePriceData.price.toNumber() / 1e6 + 0.015) * 1e6
890
- );
891
-
892
- mockMarketStats.historicalOracleData.lastOraclePriceTwap5Min = new BN(
893
- (oraclePriceData.price.toNumber() / 1e6 + 0.005) * 1e6
894
- );
895
- mockMarketStats.lastMarkPriceTwap5Min = new BN(
896
- (oraclePriceData.price.toNumber() / 1e6 - 0.005) * 1e6
897
- );
898
-
899
- console.log('starting rr:');
900
- let reservePrice: BN | undefined = undefined;
901
- if (!reservePrice) {
902
- reservePrice = calculatePrice(
903
- mockAmm.baseAssetReserve,
904
- mockAmm.quoteAssetReserve,
905
- mockAmm.pegMultiplier
906
- );
907
- }
908
-
909
- const targetPrice = oraclePriceData?.price || reservePrice;
910
- const confInterval = oraclePriceData.confidence || ZERO;
911
- const targetMarkSpreadPct = reservePrice
912
- .sub(targetPrice)
913
- .mul(BID_ASK_SPREAD_PRECISION)
914
- .div(reservePrice);
915
-
916
- const confIntervalPct = confInterval
917
- .mul(BID_ASK_SPREAD_PRECISION)
918
- .div(reservePrice);
919
-
920
- // now = now || new BN(new Date().getTime() / 1000); //todo
921
- const liveOracleStd = calculateLiveOracleStd(
922
- mockMarketStats,
923
- oraclePriceData,
924
- now
925
- );
926
- console.log('reservePrice:', reservePrice.toString());
927
- console.log('targetMarkSpreadPct:', targetMarkSpreadPct.toString());
928
- console.log('confIntervalPct:', confIntervalPct.toString());
929
- console.log('liveOracleStd:', liveOracleStd.toString());
930
-
931
- const tt = calculateSpread(mockAmm, mockMarketStats, oraclePriceData, now);
932
- console.log(tt);
933
-
934
- console.log('amm.baseAssetReserve:', mockAmm.baseAssetReserve.toString());
935
- assert(mockAmm.baseAssetReserve.eq(new BN('1000000000')));
936
- const reserves2 = calculateSpreadReserves(
937
- mockAmm,
938
- mockMarketStats,
939
- oraclePriceData,
940
- now
941
- );
942
- console.log(reserves2[0].baseAssetReserve.toString());
943
- console.log(reserves2[0].quoteAssetReserve.toString());
944
-
945
- assert(reserves2[0].baseAssetReserve.eq(new BN('1006289308')));
946
- assert(reserves2[0].quoteAssetReserve.eq(new BN('993750000')));
947
- assert(reserves2[1].baseAssetReserve.eq(new BN('993788819')));
948
- assert(reserves2[1].quoteAssetReserve.eq(new BN('1006250000')));
949
-
950
- // create imbalance for reference price offset
951
- mockAmm.baseAssetReserve = new BN(1000000000 * 1.1);
952
- mockAmm.quoteAssetReserve = new BN(1000000000 / 1.1);
953
- mockAmm.sqrtK = squareRootBN(
954
- mockAmm.baseAssetReserve.mul(mockAmm.quoteAssetReserve)
955
- );
956
-
957
- mockAmm.baseAssetAmountWithAmm = new BN(1000000000 * 0.1);
958
-
959
- const maxOffset = Math.max(
960
- mockAmm.maxSpread / 5,
961
- (PERCENTAGE_PRECISION.toNumber() / 10000) *
962
- (mockAmm.curveUpdateIntensity - 100)
963
- );
964
- const liquidityFraction = calculateInventoryLiquidityRatio(
965
- mockAmm.baseAssetAmountWithAmm,
966
- mockAmm.baseAssetReserve,
967
- mockAmm.minBaseAssetReserve,
968
- mockAmm.maxBaseAssetReserve
969
- );
970
- console.log('liquidityFraction:', liquidityFraction.toString());
971
- assert(liquidityFraction.eq(new BN(1000000))); // full
972
- const liquidityFractionSigned = liquidityFraction.mul(
973
- sigNum(mockAmm.baseAssetAmountWithAmm)
974
- );
975
- const referencePriceOffset = calculateReferencePriceOffset(
976
- reservePrice,
977
- mockMarketStats.last24HAvgFundingRate,
978
- liquidityFractionSigned,
979
- mockMarketStats.historicalOracleData.lastOraclePriceTwap5Min,
980
- mockMarketStats.lastMarkPriceTwap5Min,
981
- mockMarketStats.historicalOracleData.lastOraclePriceTwap,
982
- mockMarketStats.lastMarkPriceTwap,
983
- maxOffset
984
- );
985
- console.log('referencePriceOffset:', referencePriceOffset.toString());
986
- assert(referencePriceOffset.eq(new BN(10000)));
987
- assert(referencePriceOffset.eq(new BN(maxOffset)));
988
-
989
- // mockAmm.curveUpdateIntensity = 100;
990
- const reserves3 = calculateSpreadReserves(
991
- mockAmm,
992
- mockMarketStats,
993
- oraclePriceData,
994
- now
995
- );
996
- console.log(reserves3[0].baseAssetReserve.toString());
997
- console.log(reserves3[0].quoteAssetReserve.toString());
998
-
999
- assert(reserves3[0].baseAssetReserve.eq(new BN('1100068201')));
1000
- assert(reserves3[0].quoteAssetReserve.eq(new BN('909034546')));
1001
- assert(reserves3[1].baseAssetReserve.eq(new BN('989999998')));
1002
- assert(reserves3[1].quoteAssetReserve.eq(new BN('1010101010')));
1003
-
1004
- const p1 = calculatePrice(
1005
- reserves3[0].baseAssetReserve,
1006
- reserves3[0].quoteAssetReserve,
1007
- mockAmm.pegMultiplier
1008
- );
1009
-
1010
- const p2 = calculatePrice(
1011
- reserves3[1].baseAssetReserve,
1012
- reserves3[1].quoteAssetReserve,
1013
- mockAmm.pegMultiplier
1014
- );
1015
-
1016
- assert(p1.eq(new BN(11199437)));
1017
- assert(p2.eq(new BN(13828180)));
1018
-
1019
- mockAmm.curveUpdateIntensity = 110;
1020
- const reserves4 = calculateSpreadReserves(
1021
- mockAmm,
1022
- mockMarketStats,
1023
- oraclePriceData,
1024
- now
1025
- );
1026
-
1027
- assert(reserves4[0].baseAssetReserve.eq(new BN('1100068201')));
1028
- assert(reserves4[0].quoteAssetReserve.eq(new BN('909034546')));
1029
- assert(reserves4[1].baseAssetReserve.eq(new BN('989999998')));
1030
- assert(reserves4[1].quoteAssetReserve.eq(new BN('1010101010')));
1031
-
1032
- const p1RF = calculatePrice(
1033
- reserves4[0].baseAssetReserve,
1034
- reserves4[0].quoteAssetReserve,
1035
- mockAmm.pegMultiplier
1036
- );
1037
-
1038
- const p2RF = calculatePrice(
1039
- reserves4[1].baseAssetReserve,
1040
- reserves4[1].quoteAssetReserve,
1041
- mockAmm.pegMultiplier
1042
- );
1043
-
1044
- assert(p1RF.eq(new BN(11199437)));
1045
- assert(p2RF.eq(new BN(13828180)));
1046
- // no ref price offset at 100
1047
- mockAmm.curveUpdateIntensity = 100;
1048
- const reserves5 = calculateSpreadReserves(
1049
- mockAmm,
1050
- mockMarketStats,
1051
- oraclePriceData,
1052
- now
1053
- );
1054
-
1055
- assert(reserves5[0].baseAssetReserve.eq(new BN('1100068201')));
1056
- assert(reserves5[0].quoteAssetReserve.eq(new BN('909034546')));
1057
- assert(reserves5[1].baseAssetReserve.eq(new BN('989999998')));
1058
- assert(reserves5[1].quoteAssetReserve.eq(new BN('1010101010')));
1059
-
1060
- const p1RFNone = calculatePrice(
1061
- reserves5[0].baseAssetReserve,
1062
- reserves5[0].quoteAssetReserve,
1063
- mockAmm.pegMultiplier
1064
- );
1065
-
1066
- const p2RFNone = calculatePrice(
1067
- reserves5[1].baseAssetReserve,
1068
- reserves5[1].quoteAssetReserve,
1069
- mockAmm.pegMultiplier
1070
- );
1071
-
1072
- assert(p1RFNone.eq(new BN(11199437)));
1073
- assert(p2RFNone.eq(new BN(13828180)));
1074
- assert(p1RF.sub(p1RFNone).eq(new BN(0)));
1075
- assert(p2RF.sub(p2RFNone).eq(new BN(0))); // todo?
1076
- });
1077
- it('Spread Reserves (with negative offset)', () => {
1078
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
1079
- const mockMarket1 = myMockPerpMarkets[0];
1080
- const mockAmm = mockMarket1.amm;
1081
- const mockMarketStats = mockMarket1.marketStats;
1082
- const now = new BN(new Date().getTime() / 1000); //todo
1083
-
1084
- const oraclePriceData = {
1085
- price: new BN(13.553 * PRICE_PRECISION.toNumber()),
1086
- slot: new BN(68 + 1),
1087
- confidence: new BN(1),
1088
- hasSufficientNumberOfDataPoints: true,
1089
- isMMOracleActive: true,
1090
- } as MMOraclePriceData;
1091
-
1092
- const reserves = calculateSpreadReserves(
1093
- mockAmm,
1094
- mockMarketStats,
1095
- oraclePriceData,
1096
- now
1097
- );
1098
- assert(reserves[0].baseAssetReserve.eq(new BN('1000000000')));
1099
- assert(reserves[0].quoteAssetReserve.eq(new BN('12000000000')));
1100
- assert(reserves[1].baseAssetReserve.eq(new BN('1000000000')));
1101
- assert(reserves[1].quoteAssetReserve.eq(new BN('12000000000')));
1102
-
1103
- mockAmm.baseAssetReserve = new BN(1000000000);
1104
- mockAmm.quoteAssetReserve = new BN(1000000000);
1105
- mockAmm.sqrtK = new BN(1000000000);
1106
-
1107
- mockAmm.baseAssetAmountWithAmm = new BN(0);
1108
- mockAmm.pegMultiplier = new BN(13.553 * PEG_PRECISION.toNumber());
1109
- mockAmm.ammJitIntensity = 200;
1110
- mockAmm.curveUpdateIntensity = 200;
1111
- mockAmm.baseSpread = 2500;
1112
- mockAmm.maxSpread = 25000;
1113
-
1114
- mockMarketStats.last24HAvgFundingRate = new BN(-7590328523);
1115
-
1116
- mockMarketStats.lastMarkPriceTwap = new BN(
1117
- (oraclePriceData.price.toNumber() / 1e6 + 0.01) * 1e6
1118
- );
1119
- mockMarketStats.historicalOracleData.lastOraclePriceTwap = new BN(
1120
- (oraclePriceData.price.toNumber() / 1e6 - 0.015) * 1e6
1121
- );
1122
-
1123
- mockMarketStats.historicalOracleData.lastOraclePriceTwap5Min = new BN(
1124
- (oraclePriceData.price.toNumber() / 1e6 + 0.005) * 1e6
1125
- );
1126
- mockMarketStats.lastMarkPriceTwap5Min = new BN(
1127
- (oraclePriceData.price.toNumber() / 1e6 - 0.005) * 1e6
1128
- );
1129
-
1130
- console.log('starting rr:');
1131
- let reservePrice = undefined;
1132
- if (!reservePrice) {
1133
- reservePrice = calculatePrice(
1134
- mockAmm.baseAssetReserve,
1135
- mockAmm.quoteAssetReserve,
1136
- mockAmm.pegMultiplier
1137
- );
1138
- }
1139
-
1140
- const targetPrice = oraclePriceData?.price || reservePrice;
1141
- const confInterval = oraclePriceData.confidence || ZERO;
1142
- const targetMarkSpreadPct = reservePrice
1143
- .sub(targetPrice)
1144
- .mul(BID_ASK_SPREAD_PRECISION)
1145
- .div(reservePrice);
1146
-
1147
- const confIntervalPct = confInterval
1148
- .mul(BID_ASK_SPREAD_PRECISION)
1149
- .div(reservePrice);
1150
-
1151
- // now = now || new BN(new Date().getTime() / 1000); //todo
1152
- const liveOracleStd = calculateLiveOracleStd(
1153
- mockMarketStats,
1154
- oraclePriceData,
1155
- now
1156
- );
1157
- console.log('reservePrice:', reservePrice.toString());
1158
- console.log('targetMarkSpreadPct:', targetMarkSpreadPct.toString());
1159
- console.log('confIntervalPct:', confIntervalPct.toString());
1160
-
1161
- console.log('liveOracleStd:', liveOracleStd.toString());
1162
-
1163
- const tt = calculateSpread(mockAmm, mockMarketStats, oraclePriceData, now);
1164
- console.log(tt);
1165
-
1166
- console.log('amm.baseAssetReserve:', mockAmm.baseAssetReserve.toString());
1167
- assert(mockAmm.baseAssetReserve.eq(new BN('1000000000')));
1168
- const reserves2 = calculateSpreadReserves(
1169
- mockAmm,
1170
- mockMarketStats,
1171
- oraclePriceData,
1172
- now
1173
- );
1174
- console.log(reserves2[1].baseAssetReserve.toString());
1175
- console.log(reserves2[1].quoteAssetReserve.toString());
1176
-
1177
- assert(reserves2[0].baseAssetReserve.eq(new BN('1006289308')));
1178
- assert(reserves2[0].quoteAssetReserve.eq(new BN('993750000')));
1179
- assert(reserves2[1].baseAssetReserve.eq(new BN('993788819')));
1180
- assert(reserves2[1].quoteAssetReserve.eq(new BN('1006250000')));
1181
-
1182
- // create imbalance for reference price offset
1183
- mockAmm.baseAssetReserve = new BN(1000000000 / 1.1);
1184
- mockAmm.quoteAssetReserve = new BN(1000000000 * 1.1);
1185
- mockAmm.sqrtK = squareRootBN(
1186
- mockAmm.baseAssetReserve.mul(mockAmm.quoteAssetReserve)
1187
- );
1188
-
1189
- mockAmm.baseAssetAmountWithAmm = new BN(-1000000000 * 0.1);
1190
-
1191
- const maxOffset = Math.max(
1192
- mockAmm.maxSpread / 5,
1193
- (PERCENTAGE_PRECISION.toNumber() / 10000) *
1194
- (mockAmm.curveUpdateIntensity - 100)
1195
- );
1196
- const liquidityFraction = calculateInventoryLiquidityRatio(
1197
- mockAmm.baseAssetAmountWithAmm,
1198
- mockAmm.baseAssetReserve,
1199
- mockAmm.minBaseAssetReserve,
1200
- mockAmm.maxBaseAssetReserve
1201
- );
1202
- console.log('liquidityFraction:', liquidityFraction.toString());
1203
- assert(liquidityFraction.eq(new BN(1000000))); // full
1204
- const liquidityFractionSigned = liquidityFraction.mul(
1205
- sigNum(mockAmm.baseAssetAmountWithAmm)
1206
- );
1207
- const referencePriceOffset = calculateReferencePriceOffset(
1208
- reservePrice,
1209
- mockMarketStats.last24HAvgFundingRate,
1210
- liquidityFractionSigned,
1211
- mockMarketStats.historicalOracleData.lastOraclePriceTwap5Min,
1212
- mockMarketStats.lastMarkPriceTwap5Min,
1213
- mockMarketStats.historicalOracleData.lastOraclePriceTwap,
1214
- mockMarketStats.lastMarkPriceTwap,
1215
- maxOffset
1216
- );
1217
- console.log('referencePriceOffset:', referencePriceOffset.toString());
1218
- assert(referencePriceOffset.eq(new BN(-10000))); // neg
1219
-
1220
- // assert(referencePriceOffset.eq(new BN(maxOffset)));
1221
-
1222
- // mockAmm.curveUpdateIntensity = 100;
1223
- const reserves3 = calculateSpreadReserves(
1224
- mockAmm,
1225
- mockMarketStats,
1226
- oraclePriceData,
1227
- now
1228
- );
1229
- console.log(reserves3[0].baseAssetReserve.toString());
1230
- console.log(reserves3[0].quoteAssetReserve.toString());
1231
-
1232
- assert(reserves3[0].baseAssetReserve.eq(new BN('999999998')));
1233
- assert(reserves3[0].quoteAssetReserve.eq(new BN('1000000000')));
1234
- assert(reserves3[1].baseAssetReserve.eq(new BN('909034547')));
1235
- assert(reserves3[1].quoteAssetReserve.eq(new BN('1100068200')));
1236
-
1237
- const p1 = calculatePrice(
1238
- reserves3[0].baseAssetReserve,
1239
- reserves3[0].quoteAssetReserve,
1240
- mockAmm.pegMultiplier
1241
- );
1242
-
1243
- const p2 = calculatePrice(
1244
- reserves3[1].baseAssetReserve,
1245
- reserves3[1].quoteAssetReserve,
1246
- mockAmm.pegMultiplier
1247
- );
1248
-
1249
- assert(p1.eq(new BN(13553000)));
1250
- assert(p2.eq(new BN(16401163)));
1251
-
1252
- mockAmm.curveUpdateIntensity = 110;
1253
- const reserves4 = calculateSpreadReserves(
1254
- mockAmm,
1255
- mockMarketStats,
1256
- oraclePriceData,
1257
- now
1258
- );
1259
-
1260
- assert(reserves4[0].baseAssetReserve.eq(new BN('999999998')));
1261
- assert(reserves4[0].quoteAssetReserve.eq(new BN('1000000000')));
1262
- assert(reserves4[1].baseAssetReserve.eq(new BN('909034547')));
1263
- assert(reserves4[1].quoteAssetReserve.eq(new BN('1100068200')));
1264
-
1265
- const p1RF = calculatePrice(
1266
- reserves4[0].baseAssetReserve,
1267
- reserves4[0].quoteAssetReserve,
1268
- mockAmm.pegMultiplier
1269
- );
1270
-
1271
- const p2RF = calculatePrice(
1272
- reserves4[1].baseAssetReserve,
1273
- reserves4[1].quoteAssetReserve,
1274
- mockAmm.pegMultiplier
1275
- );
1276
-
1277
- assert(p1RF.eq(new BN(13553000)));
1278
- assert(p2RF.eq(new BN(16401163)));
1279
-
1280
- // no ref price offset at 100
1281
- mockAmm.curveUpdateIntensity = 100;
1282
- const reserves5 = calculateSpreadReserves(
1283
- mockAmm,
1284
- mockMarketStats,
1285
- oraclePriceData,
1286
- now
1287
- );
1288
-
1289
- assert(reserves5[0].baseAssetReserve.eq(new BN('999999998')));
1290
- assert(reserves5[0].quoteAssetReserve.eq(new BN('1000000000')));
1291
- assert(reserves5[1].baseAssetReserve.eq(new BN('909034547')));
1292
- assert(reserves5[1].quoteAssetReserve.eq(new BN('1100068200')));
1293
-
1294
- const p1RFNone = calculatePrice(
1295
- reserves5[0].baseAssetReserve,
1296
- reserves5[0].quoteAssetReserve,
1297
- mockAmm.pegMultiplier
1298
- );
1299
-
1300
- const p2RFNone = calculatePrice(
1301
- reserves5[1].baseAssetReserve,
1302
- reserves5[1].quoteAssetReserve,
1303
- mockAmm.pegMultiplier
1304
- );
1305
-
1306
- const rr = p2RF.sub(p2RFNone).mul(PERCENTAGE_PRECISION).div(p2RF);
1307
- assert(p1RFNone.eq(new BN(13553000)));
1308
- assert(p2RFNone.eq(new BN(16401163)));
1309
- assert(p1RF.sub(p1RFNone).eq(new BN(0))); // todo?
1310
- assert(rr.eq(new BN(0)));
1311
- });
1312
-
1313
- it('live update functions', () => {
1314
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
1315
- const mockMarket1 = myMockPerpMarkets[0];
1316
- const mockMarketStats = mockMarket1.marketStats;
1317
- const now = new BN(new Date().getTime() / 1000); //todo
1318
- const slot = 999999999;
1319
-
1320
- const oraclePriceData = {
1321
- price: new BN(13.553 * PRICE_PRECISION.toNumber()),
1322
- slot: new BN(slot),
1323
- confidence: new BN(1000),
1324
- hasSufficientNumberOfDataPoints: true,
1325
- isMMOracleActive: true,
1326
- } as MMOraclePriceData;
1327
- mockMarketStats.oracleStd = new BN(0.18 * PRICE_PRECISION.toNumber());
1328
- mockMarketStats.fundingPeriod = new BN(3600);
1329
- mockMarketStats.historicalOracleData.lastOraclePriceTwap =
1330
- oraclePriceData.price.mul(new BN(999)).div(new BN(1000));
1331
- mockMarketStats.historicalOracleData.lastOraclePriceTwapTs = now.sub(
1332
- new BN(11)
1333
- );
1334
-
1335
- const liveOracleTwap = calculateLiveOracleTwap(
1336
- mockMarketStats.historicalOracleData,
1337
- oraclePriceData,
1338
- now,
1339
- mockMarketStats.fundingPeriod
1340
- );
1341
- console.log('liveOracleTwap:', liveOracleTwap.toNumber());
1342
- assert(liveOracleTwap.eq(new BN(13539488)));
1343
-
1344
- const liveOracleStd = calculateLiveOracleStd(
1345
- mockMarketStats,
1346
- oraclePriceData,
1347
- now
1348
- );
1349
- assert(liveOracleStd.eq(new BN(13732450)));
1350
-
1351
- mockMarketStats.lastOracleConfPct = new BN(150000);
1352
- const reservePrice = new BN(13.553 * PRICE_PRECISION.toNumber());
1353
- const newConfPct = getNewOracleConfPct(
1354
- mockMarketStats,
1355
- oraclePriceData,
1356
- reservePrice,
1357
- now
1358
- );
1359
- console.log('newConfPct:', newConfPct.toString());
1360
-
1361
- assert(
1362
- now
1363
- .sub(mockMarketStats.historicalOracleData.lastOraclePriceTwapTs)
1364
- .gt(ZERO)
1365
- );
1366
-
1367
- assert(newConfPct.eq(new BN(135000)));
1368
-
1369
- const oracleGuardRails: OracleGuardRails = {
1370
- priceDivergence: {
1371
- markOraclePercentDivergence: PERCENTAGE_PRECISION.divn(10),
1372
- oracleTwap5MinPercentDivergence: PERCENTAGE_PRECISION.divn(10),
1373
- },
1374
- validity: {
1375
- slotsBeforeStaleForAmm: new BN(10),
1376
- slotsBeforeStaleForMargin: new BN(60),
1377
- confidenceIntervalMaxSize: new BN(20000),
1378
- tooVolatileRatio: new BN(5),
1379
- },
1380
- };
1381
-
1382
- // good oracle
1383
- assert(
1384
- isOracleValid(mockMarket1, oraclePriceData, oracleGuardRails, slot + 5)
1385
- );
1386
-
1387
- // conf too high
1388
- assert(
1389
- !isOracleValid(
1390
- mockMarket1,
1391
- {
1392
- price: new BN(13.553 * PRICE_PRECISION.toNumber()),
1393
- slot: new BN(slot),
1394
- confidence: new BN(13.553 * PRICE_PRECISION.toNumber() * 0.021),
1395
- hasSufficientNumberOfDataPoints: true,
1396
- isMMOracleActive: true,
1397
- } as MMOraclePriceData,
1398
- oracleGuardRails,
1399
- slot
1400
- )
1401
- );
1402
-
1403
- // not hasSufficientNumberOfDataPoints
1404
- assert(
1405
- !isOracleValid(
1406
- mockMarket1,
1407
- {
1408
- price: new BN(13.553 * PRICE_PRECISION.toNumber()),
1409
- slot: new BN(slot),
1410
- confidence: new BN(1),
1411
- hasSufficientNumberOfDataPoints: false,
1412
- isMMOracleActive: true,
1413
- } as MMOraclePriceData,
1414
- oracleGuardRails,
1415
- slot
1416
- )
1417
- );
1418
-
1419
- // negative oracle price
1420
- assert(
1421
- !isOracleValid(
1422
- mockMarket1,
1423
- {
1424
- price: new BN(-1 * PRICE_PRECISION.toNumber()),
1425
- slot: new BN(slot),
1426
- confidence: new BN(1),
1427
- hasSufficientNumberOfDataPoints: true,
1428
- isMMOracleActive: true,
1429
- } as MMOraclePriceData,
1430
- oracleGuardRails,
1431
- slot
1432
- )
1433
- );
1434
-
1435
- // too delayed for amm
1436
- assert(
1437
- !isOracleValid(
1438
- mockMarket1,
1439
- {
1440
- price: new BN(13.553 * PRICE_PRECISION.toNumber()),
1441
- slot: new BN(slot),
1442
- confidence: new BN(1),
1443
- hasSufficientNumberOfDataPoints: true,
1444
- isMMOracleActive: true,
1445
- } as MMOraclePriceData,
1446
- oracleGuardRails,
1447
- slot + 100
1448
- )
1449
- );
1450
-
1451
- // im passing stale slot (should not call oracle invalid)
1452
- assert(
1453
- isOracleValid(
1454
- mockMarket1,
1455
- {
1456
- price: new BN(13.553 * PRICE_PRECISION.toNumber()),
1457
- slot: new BN(slot + 100),
1458
- confidence: new BN(1),
1459
- hasSufficientNumberOfDataPoints: true,
1460
- isMMOracleActive: true,
1461
- } as MMOraclePriceData,
1462
- oracleGuardRails,
1463
- slot
1464
- )
1465
- );
1466
-
1467
- // too volatile (more than 5x higher)
1468
- assert(
1469
- !isOracleValid(
1470
- mockMarket1,
1471
- {
1472
- price: new BN(113.553 * PRICE_PRECISION.toNumber()),
1473
- slot: new BN(slot + 5),
1474
- confidence: new BN(1),
1475
- hasSufficientNumberOfDataPoints: true,
1476
- isMMOracleActive: true,
1477
- } as MMOraclePriceData,
1478
- oracleGuardRails,
1479
- slot
1480
- )
1481
- );
1482
-
1483
- // too volatile (more than 1/5 lower)
1484
- assert(
1485
- !isOracleValid(
1486
- mockMarket1,
1487
- {
1488
- price: new BN(0.553 * PRICE_PRECISION.toNumber()),
1489
- slot: new BN(slot + 5),
1490
- confidence: new BN(1),
1491
- hasSufficientNumberOfDataPoints: true,
1492
- isMMOracleActive: true,
1493
- } as MMOraclePriceData,
1494
- oracleGuardRails,
1495
- slot
1496
- )
1497
- );
1498
- });
1499
-
1500
- it('predicted funding rate mock1', () => {
1501
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
1502
- const mockMarket1 = myMockPerpMarkets[0];
1503
-
1504
- // make it like RNDR
1505
- const now = new BN(1688878353);
1506
-
1507
- mockMarket1.marketStats.fundingPeriod = new BN(3600);
1508
- mockMarket1.lastFundingRateTs = new BN(1688860817);
1509
-
1510
- const currentMarkPrice = new BN(1.9843 * PRICE_PRECISION.toNumber()); // trading at a premium
1511
- const mmOraclePriceData: MMOraclePriceData = {
1512
- price: new BN(1.9535 * PRICE_PRECISION.toNumber()),
1513
- slot: new BN(0),
1514
- confidence: new BN(1),
1515
- hasSufficientNumberOfDataPoints: true,
1516
- isMMOracleActive: true,
1517
- };
1518
- mockMarket1.marketStats.historicalOracleData.lastOraclePrice = new BN(
1519
- 1.9535 * PRICE_PRECISION.toNumber()
1520
- );
1521
-
1522
- // mockMarket1.amm.pegMultiplier = new BN(1.897573 * 1e3);
1523
-
1524
- mockMarket1.marketStats.lastMarkPriceTwap = new BN(
1525
- 1.945594 * PRICE_PRECISION.toNumber()
1526
- );
1527
- mockMarket1.marketStats.lastBidPriceTwap = new BN(
1528
- 1.941629 * PRICE_PRECISION.toNumber()
1529
- );
1530
- mockMarket1.marketStats.lastAskPriceTwap = new BN(
1531
- 1.94956 * PRICE_PRECISION.toNumber()
1532
- );
1533
- mockMarket1.marketStats.lastMarkPriceTwapTs = new BN(1688877729);
1534
-
1535
- mockMarket1.marketStats.historicalOracleData.lastOraclePriceTwap = new BN(
1536
- 1.942449 * PRICE_PRECISION.toNumber()
1537
- );
1538
- mockMarket1.marketStats.historicalOracleData.lastOraclePriceTwapTs = new BN(
1539
- 1688878333
1540
- );
1541
-
1542
- const [
1543
- _markTwapLive,
1544
- _oracleTwapLive,
1545
- _lowerboundEst,
1546
- _cappedAltEst,
1547
- _interpEst,
1548
- ] = calculateAllEstimatedFundingRate(
1549
- mockMarket1,
1550
- mmOraclePriceData,
1551
- mmOraclePriceData as unknown as OraclePriceData,
1552
- currentMarkPrice,
1553
- now
1554
- );
1555
-
1556
- const [markTwapLive, oracleTwapLive, est1, est2] =
1557
- calculateLongShortFundingRateAndLiveTwaps(
1558
- mockMarket1,
1559
- mmOraclePriceData,
1560
- mmOraclePriceData as unknown as OraclePriceData,
1561
- currentMarkPrice,
1562
- now
1563
- );
1564
-
1565
- // console.log(markTwapLive.toString());
1566
- // console.log(oracleTwapLive.toString());
1567
- // console.log(est1.toString());
1568
- // console.log(est2.toString());
1569
-
1570
- assert(markTwapLive.eq(new BN('1949826')));
1571
- assert(oracleTwapLive.eq(new BN('1942510')));
1572
- assert(est1.eq(new BN('14858')));
1573
- assert(est2.eq(new BN('14858')));
1574
- });
1575
-
1576
- it('predicted funding rate mock2', () => {
1577
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
1578
- const mockMarket1 = myMockPerpMarkets[0];
1579
-
1580
- // make it like OP
1581
- const now = new BN(1688881915);
1582
-
1583
- mockMarket1.marketStats.fundingPeriod = new BN(3600);
1584
- mockMarket1.lastFundingRateTs = new BN(1688864415);
1585
-
1586
- const currentMarkPrice = new BN(1.2242 * PRICE_PRECISION.toNumber()); // trading at a premium
1587
- const mmOraclePriceData: MMOraclePriceData = {
1588
- price: new BN(1.224 * PRICE_PRECISION.toNumber()),
1589
- slot: new BN(0),
1590
- confidence: new BN(1),
1591
- hasSufficientNumberOfDataPoints: true,
1592
- isMMOracleActive: true,
1593
- };
1594
- mockMarket1.marketStats.historicalOracleData.lastOraclePrice = new BN(
1595
- 1.9535 * PRICE_PRECISION.toNumber()
1596
- );
1597
-
1598
- // mockMarket1.amm.pegMultiplier = new BN(1.897573 * 1e3);
1599
-
1600
- mockMarket1.marketStats.lastMarkPriceTwap = new BN(
1601
- 1.218363 * PRICE_PRECISION.toNumber()
1602
- );
1603
- mockMarket1.marketStats.lastBidPriceTwap = new BN(
1604
- 1.218363 * PRICE_PRECISION.toNumber()
1605
- );
1606
- mockMarket1.marketStats.lastAskPriceTwap = new BN(
1607
- 1.218364 * PRICE_PRECISION.toNumber()
1608
- );
1609
- mockMarket1.marketStats.lastMarkPriceTwapTs = new BN(1688878815);
1610
-
1611
- mockMarket1.marketStats.historicalOracleData.lastOraclePriceTwap = new BN(
1612
- 1.220964 * PRICE_PRECISION.toNumber()
1613
- );
1614
- mockMarket1.marketStats.historicalOracleData.lastOraclePriceTwapTs = new BN(
1615
- 1688879991
1616
- );
1617
-
1618
- const [
1619
- _markTwapLive,
1620
- _oracleTwapLive,
1621
- _lowerboundEst,
1622
- _cappedAltEst,
1623
- _interpEst,
1624
- ] = calculateAllEstimatedFundingRate(
1625
- mockMarket1,
1626
- mmOraclePriceData,
1627
- mmOraclePriceData as unknown as OraclePriceData,
1628
- currentMarkPrice,
1629
- now
1630
- );
1631
-
1632
- // console.log(_markTwapLive.toString());
1633
- // console.log(_oracleTwapLive.toString());
1634
- // console.log(_lowerboundEst.toString());
1635
- // console.log(_cappedAltEst.toString());
1636
- // console.log(_interpEst.toString());
1637
- // console.log('-----');
1638
-
1639
- const [markTwapLive, oracleTwapLive, est1, est2] =
1640
- calculateLongShortFundingRateAndLiveTwaps(
1641
- mockMarket1,
1642
- mmOraclePriceData,
1643
- mmOraclePriceData as unknown as OraclePriceData,
1644
- currentMarkPrice,
1645
- now
1646
- );
1647
-
1648
- console.log(
1649
- 'markTwapLive:',
1650
- mockMarket1.marketStats.lastMarkPriceTwap.toString(),
1651
- '->',
1652
- markTwapLive.toString()
1653
- );
1654
- console.log(
1655
- 'oracTwapLive:',
1656
- mockMarket1.marketStats.historicalOracleData.lastOraclePriceTwap.toString(),
1657
- '->',
1658
- oracleTwapLive.toString()
1659
- );
1660
- console.log('pred funding:', est1.toString(), est2.toString());
1661
-
1662
- assert(markTwapLive.eq(new BN('1222131')));
1663
- assert(oracleTwapLive.eq(new BN('1222586')));
1664
- assert(est1.eq(est2));
1665
- assert(est2.eq(new BN('1247')));
1666
- });
1667
-
1668
- it('predicted funding rate mock clamp', () => {
1669
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
1670
- const mockMarket1 = myMockPerpMarkets[0];
1671
-
1672
- // make it like OP
1673
- const now = new BN(1688881915);
1674
-
1675
- mockMarket1.marketStats.fundingPeriod = new BN(3600);
1676
- mockMarket1.lastFundingRateTs = new BN(1688864415);
1677
-
1678
- const currentMarkPrice = new BN(1.2242 * PRICE_PRECISION.toNumber()); // trading at a premium
1679
- const mmOraclePriceData: MMOraclePriceData = {
1680
- price: new BN(1.924 * PRICE_PRECISION.toNumber()),
1681
- slot: new BN(0),
1682
- confidence: new BN(1),
1683
- hasSufficientNumberOfDataPoints: true,
1684
- isMMOracleActive: true,
1685
- } as MMOraclePriceData;
1686
- mockMarket1.marketStats.historicalOracleData.lastOraclePrice = new BN(
1687
- 1.9535 * PRICE_PRECISION.toNumber()
1688
- );
1689
-
1690
- // mockMarket1.amm.pegMultiplier = new BN(1.897573 * 1e3);
1691
-
1692
- mockMarket1.marketStats.lastMarkPriceTwap = new BN(
1693
- 1.218363 * PRICE_PRECISION.toNumber()
1694
- );
1695
- mockMarket1.marketStats.lastBidPriceTwap = new BN(
1696
- 1.218363 * PRICE_PRECISION.toNumber()
1697
- );
1698
- mockMarket1.marketStats.lastAskPriceTwap = new BN(
1699
- 1.218364 * PRICE_PRECISION.toNumber()
1700
- );
1701
- mockMarket1.marketStats.lastMarkPriceTwapTs = new BN(1688878815);
1702
-
1703
- mockMarket1.marketStats.historicalOracleData.lastOraclePriceTwap = new BN(
1704
- 1.820964 * PRICE_PRECISION.toNumber()
1705
- );
1706
- mockMarket1.marketStats.historicalOracleData.lastOraclePriceTwapTs = new BN(
1707
- 1688879991
1708
- );
1709
- mockMarket1.contractTier = ContractTier.A;
1710
-
1711
- const [
1712
- _markTwapLive,
1713
- _oracleTwapLive,
1714
- _lowerboundEst,
1715
- _cappedAltEst,
1716
- _interpEst,
1717
- ] = calculateAllEstimatedFundingRate(
1718
- mockMarket1,
1719
- mmOraclePriceData,
1720
- mmOraclePriceData as unknown as OraclePriceData,
1721
- currentMarkPrice,
1722
- now
1723
- );
1724
-
1725
- // console.log(_markTwapLive.toString());
1726
- // console.log(_oracleTwapLive.toString());
1727
- // console.log(_lowerboundEst.toString());
1728
- // console.log(_cappedAltEst.toString());
1729
- // console.log(_interpEst.toString());
1730
- // console.log('-----');
1731
-
1732
- let [markTwapLive, oracleTwapLive, est1, est2] =
1733
- calculateLongShortFundingRateAndLiveTwaps(
1734
- mockMarket1,
1735
- mmOraclePriceData,
1736
- mmOraclePriceData as unknown as OraclePriceData,
1737
- currentMarkPrice,
1738
- now
1739
- );
1740
-
1741
- console.log(
1742
- 'markTwapLive:',
1743
- mockMarket1.marketStats.lastMarkPriceTwap.toString(),
1744
- '->',
1745
- markTwapLive.toString()
1746
- );
1747
- console.log(
1748
- 'oracTwapLive:',
1749
- mockMarket1.marketStats.historicalOracleData.lastOraclePriceTwap.toString(),
1750
- '->',
1751
- oracleTwapLive.toString()
1752
- );
1753
- console.log('pred funding:', est1.toString(), est2.toString());
1754
-
1755
- assert(markTwapLive.eq(new BN('1680634')));
1756
- assert(oracleTwapLive.eq(new BN('1876031')));
1757
- assert(est1.eq(est2));
1758
- assert(est2.eq(new BN('-126261')));
1759
-
1760
- mockMarket1.contractTier = ContractTier.C;
1761
-
1762
- [markTwapLive, oracleTwapLive, est1, est2] =
1763
- calculateLongShortFundingRateAndLiveTwaps(
1764
- mockMarket1,
1765
- mmOraclePriceData,
1766
- mmOraclePriceData as unknown as OraclePriceData,
1767
- currentMarkPrice,
1768
- now
1769
- );
1770
-
1771
- console.log(
1772
- 'markTwapLive:',
1773
- mockMarket1.marketStats.lastMarkPriceTwap.toString(),
1774
- '->',
1775
- markTwapLive.toString()
1776
- );
1777
- console.log(
1778
- 'oracTwapLive:',
1779
- mockMarket1.marketStats.historicalOracleData.lastOraclePriceTwap.toString(),
1780
- '->',
1781
- oracleTwapLive.toString()
1782
- );
1783
- console.log('pred funding:', est1.toString(), est2.toString());
1784
-
1785
- assert(markTwapLive.eq(new BN('1680634')));
1786
- assert(oracleTwapLive.eq(new BN('1876031')));
1787
- assert(est1.eq(est2));
1788
- assert(est2.eq(new BN('-208332')));
1789
-
1790
- mockMarket1.contractTier = ContractTier.SPECULATIVE;
1791
-
1792
- [markTwapLive, oracleTwapLive, est1, est2] =
1793
- calculateLongShortFundingRateAndLiveTwaps(
1794
- mockMarket1,
1795
- mmOraclePriceData,
1796
- mmOraclePriceData as unknown as OraclePriceData,
1797
- currentMarkPrice,
1798
- now
1799
- );
1800
-
1801
- console.log(
1802
- 'markTwapLive:',
1803
- mockMarket1.marketStats.lastMarkPriceTwap.toString(),
1804
- '->',
1805
- markTwapLive.toString()
1806
- );
1807
- console.log(
1808
- 'oracTwapLive:',
1809
- mockMarket1.marketStats.historicalOracleData.lastOraclePriceTwap.toString(),
1810
- '->',
1811
- oracleTwapLive.toString()
1812
- );
1813
- console.log('pred funding:', est1.toString(), est2.toString());
1814
-
1815
- assert(markTwapLive.eq(new BN('1680634')));
1816
- assert(oracleTwapLive.eq(new BN('1876031')));
1817
- assert(est1.eq(est2));
1818
- assert(est2.eq(new BN('-416666')));
1819
- });
1820
-
1821
- it('orderbook L2 gen (no topOfBookQuoteAmounts, 10 numOrders, low liquidity)', async () => {
1822
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
1823
-
1824
- const mockMarket1: PerpMarketAccount = myMockPerpMarkets[0];
1825
- const cc = 38104569;
1826
- mockMarket1.amm.baseAssetReserve = new BN(cc).mul(BASE_PRECISION);
1827
- mockMarket1.amm.maxBaseAssetReserve = mockMarket1.amm.baseAssetReserve.add(
1828
- new BN(1234835)
1829
- );
1830
- mockMarket1.amm.minBaseAssetReserve =
1831
- mockMarket1.amm.baseAssetReserve.sub(BASE_PRECISION);
1832
- mockMarket1.amm.quoteAssetReserve = new BN(cc).mul(BASE_PRECISION);
1833
- mockMarket1.amm.pegMultiplier = new BN(18.32 * PEG_PRECISION.toNumber());
1834
- mockMarket1.amm.sqrtK = new BN(cc).mul(BASE_PRECISION);
1835
-
1836
- const now = new BN(1688881915);
1837
-
1838
- const mmOraclePriceData: MMOraclePriceData = {
1839
- price: new BN(18.624 * PRICE_PRECISION.toNumber()),
1840
- slot: new BN(0),
1841
- confidence: new BN(1),
1842
- hasSufficientNumberOfDataPoints: true,
1843
- isMMOracleActive: true,
1844
- } as MMOraclePriceData;
1845
- mockMarket1.marketStats.historicalOracleData.lastOraclePrice = new BN(
1846
- 18.5535 * PRICE_PRECISION.toNumber()
1847
- );
1848
-
1849
- const updatedAmm = calculateUpdatedAMM(mockMarket1.amm, mmOraclePriceData);
1850
-
1851
- const [openBids, openAsks] = calculateMarketOpenBidAsk(
1852
- updatedAmm.baseAssetReserve,
1853
- updatedAmm.minBaseAssetReserve,
1854
- updatedAmm.maxBaseAssetReserve,
1855
- mockMarket1.orderStepSize
1856
- );
1857
-
1858
- const generator = getVammL2Generator({
1859
- marketAccount: mockMarket1,
1860
- mmOraclePriceData,
1861
- numOrders: 10,
1862
- now,
1863
- topOfBookQuoteAmounts: [],
1864
- });
1865
-
1866
- const bids = Array.from(generator.getL2Bids());
1867
- // console.log(bids);
1868
-
1869
- const totalBidSize = bids.reduce((total: BN, order: L2Level) => {
1870
- return total.add(order.size);
1871
- }, ZERO);
1872
-
1873
- console.log(
1874
- 'totalBidSize:',
1875
- totalBidSize.toString(),
1876
- 'openBids:',
1877
- openBids.toString()
1878
- );
1879
- assert(totalBidSize.sub(openBids).abs().lt(new BN(10))); // smol err
1880
- assert(totalBidSize.sub(openBids).lt(ZERO)); // under estimation
1881
-
1882
- const asks = Array.from(generator.getL2Asks());
1883
- // console.log(asks);
1884
-
1885
- const totalAskSize = asks.reduce((total: BN, order: L2Level) => {
1886
- return total.add(order.size);
1887
- }, ZERO);
1888
- console.log(
1889
- 'totalAskSize:',
1890
- totalAskSize.toString(),
1891
- 'openAsks:',
1892
- openAsks.toString()
1893
- );
1894
- assert(totalAskSize.sub(openAsks.abs()).lte(new BN(5))); // only tiny rounding errors
1895
- });
1896
-
1897
- it('orderbook L2 gen (no topOfBookQuoteAmounts, 10 numOrders)', async () => {
1898
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
1899
-
1900
- const mockMarket1: PerpMarketAccount = myMockPerpMarkets[0];
1901
- const cc = 38104569;
1902
- mockMarket1.amm.baseAssetReserve = new BN(cc).mul(BASE_PRECISION);
1903
- mockMarket1.amm.maxBaseAssetReserve = mockMarket1.amm.baseAssetReserve.mul(
1904
- new BN(2)
1905
- );
1906
- mockMarket1.amm.minBaseAssetReserve = mockMarket1.amm.baseAssetReserve.div(
1907
- new BN(2)
1908
- );
1909
- mockMarket1.amm.quoteAssetReserve = new BN(cc).mul(BASE_PRECISION);
1910
- mockMarket1.amm.pegMultiplier = new BN(18.32 * PEG_PRECISION.toNumber());
1911
- mockMarket1.amm.sqrtK = new BN(cc).mul(BASE_PRECISION);
1912
-
1913
- const now = new BN(1688881915);
1914
-
1915
- const mmOraclePriceData: MMOraclePriceData = {
1916
- price: new BN(18.624 * PRICE_PRECISION.toNumber()),
1917
- slot: new BN(0),
1918
- confidence: new BN(1),
1919
- hasSufficientNumberOfDataPoints: true,
1920
- isMMOracleActive: true,
1921
- } as MMOraclePriceData;
1922
- mockMarket1.marketStats.historicalOracleData.lastOraclePrice = new BN(
1923
- 18.5535 * PRICE_PRECISION.toNumber()
1924
- );
1925
-
1926
- const updatedAmm = calculateUpdatedAMM(mockMarket1.amm, mmOraclePriceData);
1927
-
1928
- const [openBids, openAsks] = calculateMarketOpenBidAsk(
1929
- updatedAmm.baseAssetReserve,
1930
- updatedAmm.minBaseAssetReserve,
1931
- updatedAmm.maxBaseAssetReserve,
1932
- mockMarket1.orderStepSize
1933
- );
1934
-
1935
- const generator = getVammL2Generator({
1936
- marketAccount: mockMarket1,
1937
- mmOraclePriceData,
1938
- numOrders: 10,
1939
- now,
1940
- topOfBookQuoteAmounts: [],
1941
- });
1942
-
1943
- const bids = Array.from(generator.getL2Bids());
1944
- // console.log(bids);
1945
-
1946
- const totalBidSize = bids.reduce((total: BN, order: L2Level) => {
1947
- return total.add(order.size);
1948
- }, ZERO);
1949
-
1950
- console.log(
1951
- 'totalBidSize:',
1952
- totalBidSize.toString(),
1953
- 'openBids:',
1954
- openBids.toString()
1955
- );
1956
- assert(totalBidSize.eq(openBids));
1957
-
1958
- const asks = Array.from(generator.getL2Asks());
1959
- // console.log(asks);
1960
-
1961
- const totalAskSize = asks.reduce((total: BN, order: L2Level) => {
1962
- return total.add(order.size);
1963
- }, ZERO);
1964
- console.log(
1965
- 'totalAskSize:',
1966
- totalAskSize.toString(),
1967
- 'openAsks:',
1968
- openAsks.toString()
1969
- );
1970
- assert(totalAskSize.sub(openAsks.abs()).lte(new BN(5))); // only tiny rounding errors
1971
- });
1972
-
1973
- it('orderbook L2 gen (4 topOfBookQuoteAmounts, 10 numOrders)', async () => {
1974
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
1975
-
1976
- const mockMarket1: PerpMarketAccount = myMockPerpMarkets[0];
1977
- const cc = 38104569;
1978
- mockMarket1.amm.baseAssetReserve = new BN(cc).mul(BASE_PRECISION);
1979
- mockMarket1.amm.maxBaseAssetReserve = mockMarket1.amm.baseAssetReserve.mul(
1980
- new BN(2)
1981
- );
1982
- mockMarket1.amm.minBaseAssetReserve = mockMarket1.amm.baseAssetReserve.div(
1983
- new BN(2)
1984
- );
1985
- mockMarket1.amm.quoteAssetReserve = new BN(cc).mul(BASE_PRECISION);
1986
- mockMarket1.amm.pegMultiplier = new BN(18.32 * PEG_PRECISION.toNumber());
1987
- mockMarket1.amm.sqrtK = new BN(cc).mul(BASE_PRECISION);
1988
-
1989
- const now = new BN(1688881915);
1990
-
1991
- const mmOraclePriceData: MMOraclePriceData = {
1992
- price: new BN(18.624 * PRICE_PRECISION.toNumber()),
1993
- slot: new BN(0),
1994
- confidence: new BN(1),
1995
- hasSufficientNumberOfDataPoints: true,
1996
- isMMOracleActive: true,
1997
- } as MMOraclePriceData;
1998
- mockMarket1.marketStats.historicalOracleData.lastOraclePrice = new BN(
1999
- 18.5535 * PRICE_PRECISION.toNumber()
2000
- );
2001
-
2002
- const updatedAmm = calculateUpdatedAMM(mockMarket1.amm, mmOraclePriceData);
2003
-
2004
- const [openBids, openAsks] = calculateMarketOpenBidAsk(
2005
- updatedAmm.baseAssetReserve,
2006
- updatedAmm.minBaseAssetReserve,
2007
- updatedAmm.maxBaseAssetReserve,
2008
- mockMarket1.orderStepSize
2009
- );
2010
-
2011
- assert(!openAsks.eq(openBids));
2012
-
2013
- const generator = getVammL2Generator({
2014
- marketAccount: mockMarket1,
2015
- mmOraclePriceData,
2016
- numOrders: 10,
2017
- now,
2018
- topOfBookQuoteAmounts: [
2019
- new BN(10).mul(QUOTE_PRECISION),
2020
- new BN(100).mul(QUOTE_PRECISION),
2021
- new BN(1000).mul(QUOTE_PRECISION),
2022
- new BN(10000).mul(QUOTE_PRECISION),
2023
- ],
2024
- });
2025
-
2026
- const bids = Array.from(generator.getL2Bids());
2027
- // console.log(bids);
2028
-
2029
- const totalBidSize = bids.reduce((total: BN, order: L2Level) => {
2030
- return total.add(order.size);
2031
- }, ZERO);
2032
-
2033
- console.log(
2034
- 'totalBidSize:',
2035
- totalBidSize.toString(),
2036
- 'openBids:',
2037
- openBids.toString()
2038
- );
2039
- assert(totalBidSize.eq(openBids));
2040
-
2041
- const asks = Array.from(generator.getL2Asks());
2042
- // console.log(asks);
2043
-
2044
- const totalAskSize = asks.reduce((total: BN, order: L2Level) => {
2045
- return total.add(order.size);
2046
- }, ZERO);
2047
- console.log(
2048
- 'totalAskSize:',
2049
- totalAskSize.toString(),
2050
- 'openAsks:',
2051
- openAsks.toString()
2052
- );
2053
- assert(totalAskSize.sub(openAsks.abs()).lte(new BN(5))); // only tiny rounding errors
2054
- });
2055
-
2056
- it('orderbook L2 gen (4 topOfBookQuoteAmounts, 10 numOrders, low bid liquidity)', async () => {
2057
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
2058
-
2059
- const mockMarket1: PerpMarketAccount = myMockPerpMarkets[0];
2060
- const cc = 38104569;
2061
- mockMarket1.amm.baseAssetReserve = new BN(cc).mul(BASE_PRECISION);
2062
- mockMarket1.amm.maxBaseAssetReserve =
2063
- mockMarket1.amm.baseAssetReserve.add(BASE_PRECISION); // only 1 base
2064
- mockMarket1.amm.minBaseAssetReserve = mockMarket1.amm.baseAssetReserve.div(
2065
- new BN(2)
2066
- );
2067
- mockMarket1.amm.quoteAssetReserve = new BN(cc).mul(BASE_PRECISION);
2068
- mockMarket1.amm.pegMultiplier = new BN(18.32 * PEG_PRECISION.toNumber());
2069
- mockMarket1.amm.sqrtK = new BN(cc).mul(BASE_PRECISION);
2070
-
2071
- const now = new BN(1688881915);
2072
-
2073
- const mmOraclePriceData: MMOraclePriceData = {
2074
- price: new BN(18.624 * PRICE_PRECISION.toNumber()),
2075
- slot: new BN(0),
2076
- confidence: new BN(1),
2077
- hasSufficientNumberOfDataPoints: true,
2078
- isMMOracleActive: true,
2079
- } as MMOraclePriceData;
2080
- mockMarket1.marketStats.historicalOracleData.lastOraclePrice = new BN(
2081
- 18.5535 * PRICE_PRECISION.toNumber()
2082
- );
2083
-
2084
- const updatedAmm = calculateUpdatedAMM(mockMarket1.amm, mmOraclePriceData);
2085
-
2086
- const [openBids, openAsks] = calculateMarketOpenBidAsk(
2087
- updatedAmm.baseAssetReserve,
2088
- updatedAmm.minBaseAssetReserve,
2089
- updatedAmm.maxBaseAssetReserve,
2090
- mockMarket1.orderStepSize
2091
- );
2092
-
2093
- assert(!openAsks.eq(openBids));
2094
-
2095
- const generator = getVammL2Generator({
2096
- marketAccount: mockMarket1,
2097
- mmOraclePriceData,
2098
- numOrders: 10,
2099
- now,
2100
- topOfBookQuoteAmounts: [
2101
- new BN(10).mul(QUOTE_PRECISION),
2102
- new BN(100).mul(QUOTE_PRECISION),
2103
- new BN(1000).mul(QUOTE_PRECISION),
2104
- new BN(10000).mul(QUOTE_PRECISION),
2105
- ],
2106
- });
2107
-
2108
- const bids = Array.from(generator.getL2Bids());
2109
- assert(bids.length == 2);
2110
- console.log(bids[0].size.toString());
2111
- console.log(bids[1].size.toString());
2112
-
2113
- const totalBidSize = bids.reduce((total: BN, order: L2Level) => {
2114
- return total.add(order.size);
2115
- }, ZERO);
2116
-
2117
- console.log(
2118
- 'totalBidSize:',
2119
- totalBidSize.toString(),
2120
- 'openBids:',
2121
- openBids.toString()
2122
- );
2123
- assert(totalBidSize.eq(openBids));
2124
-
2125
- const asks = Array.from(generator.getL2Asks());
2126
- // console.log(asks);
2127
-
2128
- const totalAskSize = asks.reduce((total: BN, order: L2Level) => {
2129
- return total.add(order.size);
2130
- }, ZERO);
2131
- console.log(
2132
- 'totalAskSize:',
2133
- totalAskSize.toString(),
2134
- 'openAsks:',
2135
- openAsks.toString()
2136
- );
2137
- assert(totalAskSize.sub(openAsks.abs()).lte(new BN(5))); // only tiny rounding errors
2138
- });
2139
-
2140
- it('orderbook L2 gen (4 topOfBookQuoteAmounts, 10 numOrders, low ask liquidity)', async () => {
2141
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
2142
-
2143
- const mockMarket1: PerpMarketAccount = myMockPerpMarkets[0];
2144
- const cc = 38104569;
2145
- mockMarket1.amm.baseAssetReserve = new BN(cc).mul(BASE_PRECISION);
2146
- mockMarket1.amm.maxBaseAssetReserve = mockMarket1.amm.baseAssetReserve.add(
2147
- BASE_PRECISION.mul(new BN(1000))
2148
- ); // 1000 base
2149
- mockMarket1.amm.minBaseAssetReserve = mockMarket1.amm.baseAssetReserve.sub(
2150
- BASE_PRECISION.div(new BN(2))
2151
- ); // only .5 base
2152
- mockMarket1.amm.quoteAssetReserve = new BN(cc).mul(BASE_PRECISION);
2153
- mockMarket1.amm.pegMultiplier = new BN(18.32 * PEG_PRECISION.toNumber());
2154
- mockMarket1.amm.sqrtK = new BN(cc).mul(BASE_PRECISION);
2155
-
2156
- const now = new BN(1688881915);
2157
-
2158
- const mmOraclePriceData: MMOraclePriceData = {
2159
- price: new BN(18.624 * PRICE_PRECISION.toNumber()),
2160
- slot: new BN(0),
2161
- confidence: new BN(1),
2162
- hasSufficientNumberOfDataPoints: true,
2163
- isMMOracleActive: true,
2164
- };
2165
- mockMarket1.marketStats.historicalOracleData.lastOraclePrice = new BN(
2166
- 18.5535 * PRICE_PRECISION.toNumber()
2167
- );
2168
-
2169
- const updatedAmm = calculateUpdatedAMM(mockMarket1.amm, mmOraclePriceData);
2170
-
2171
- const [openBids, openAsks] = calculateMarketOpenBidAsk(
2172
- updatedAmm.baseAssetReserve,
2173
- updatedAmm.minBaseAssetReserve,
2174
- updatedAmm.maxBaseAssetReserve,
2175
- mockMarket1.orderStepSize
2176
- );
2177
-
2178
- assert(!openAsks.eq(openBids));
2179
-
2180
- const generator = getVammL2Generator({
2181
- marketAccount: mockMarket1,
2182
- mmOraclePriceData,
2183
- numOrders: 10,
2184
- now,
2185
- topOfBookQuoteAmounts: [
2186
- new BN(10).mul(QUOTE_PRECISION),
2187
- new BN(100).mul(QUOTE_PRECISION),
2188
- new BN(1000).mul(QUOTE_PRECISION),
2189
- new BN(10000).mul(QUOTE_PRECISION),
2190
- ],
2191
- });
2192
-
2193
- const bids = Array.from(generator.getL2Bids());
2194
-
2195
- const totalBidSize = bids.reduce((total: BN, order: L2Level) => {
2196
- return total.add(order.size);
2197
- }, ZERO);
2198
-
2199
- console.log(
2200
- 'totalBidSize:',
2201
- totalBidSize.toString(),
2202
- 'openBids:',
2203
- openBids.toString()
2204
- );
2205
- assert(totalBidSize.sub(openBids).abs().lt(new BN(5)));
2206
-
2207
- const asks = Array.from(generator.getL2Asks());
2208
- // console.log(asks);
2209
-
2210
- assert(asks.length == 1);
2211
- console.log(asks[0].size.toString());
2212
- const totalAskSize = asks.reduce((total: BN, order: L2Level) => {
2213
- return total.add(order.size);
2214
- }, ZERO);
2215
- console.log(
2216
- 'totalAskSize:',
2217
- totalAskSize.toString(),
2218
- 'openAsks:',
2219
- openAsks.toString()
2220
- );
2221
- assert(totalAskSize.sub(openAsks.abs()).lte(new BN(5))); // only tiny rounding errors
2222
- });
2223
-
2224
- it('orderbook L2 gen (no topOfBookQuoteAmounts, 10 numOrders, no liquidity)', async () => {
2225
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
2226
-
2227
- const mockMarket1: PerpMarketAccount = myMockPerpMarkets[0];
2228
- const cc = 38104569;
2229
- mockMarket1.amm.baseAssetReserve = new BN(cc).mul(BASE_PRECISION);
2230
- mockMarket1.marketStats.minOrderSize = new BN(5);
2231
- mockMarket1.amm.maxBaseAssetReserve = mockMarket1.amm.baseAssetReserve.add(
2232
- new BN(9)
2233
- );
2234
- mockMarket1.amm.minBaseAssetReserve = mockMarket1.amm.baseAssetReserve.sub(
2235
- new BN(9)
2236
- );
2237
- mockMarket1.amm.quoteAssetReserve = new BN(cc).mul(BASE_PRECISION);
2238
- mockMarket1.amm.pegMultiplier = new BN(18.32 * PEG_PRECISION.toNumber());
2239
- mockMarket1.amm.sqrtK = new BN(cc).mul(BASE_PRECISION);
2240
-
2241
- const now = new BN(1688881915);
2242
-
2243
- const mmOraclePriceData: MMOraclePriceData = {
2244
- price: new BN(18.624 * PRICE_PRECISION.toNumber()),
2245
- slot: new BN(0),
2246
- confidence: new BN(1),
2247
- hasSufficientNumberOfDataPoints: true,
2248
- isMMOracleActive: true,
2249
- } as MMOraclePriceData;
2250
- mockMarket1.marketStats.historicalOracleData.lastOraclePrice = new BN(
2251
- 18.5535 * PRICE_PRECISION.toNumber()
2252
- );
2253
-
2254
- const updatedAmm = calculateUpdatedAMM(mockMarket1.amm, mmOraclePriceData);
2255
-
2256
- const [openBids, openAsks] = calculateMarketOpenBidAsk(
2257
- updatedAmm.baseAssetReserve,
2258
- updatedAmm.minBaseAssetReserve,
2259
- updatedAmm.maxBaseAssetReserve,
2260
- mockMarket1.orderStepSize
2261
- );
2262
-
2263
- const generator = getVammL2Generator({
2264
- marketAccount: mockMarket1,
2265
- mmOraclePriceData,
2266
- numOrders: 10,
2267
- now,
2268
- topOfBookQuoteAmounts: [],
2269
- });
2270
-
2271
- const bids = Array.from(generator.getL2Bids());
2272
- // console.log(bids);
2273
-
2274
- const totalBidSize = bids.reduce((total: BN, order: L2Level) => {
2275
- return total.add(order.size);
2276
- }, ZERO);
2277
-
2278
- console.log(
2279
- 'totalBidSize:',
2280
- totalBidSize.toString(),
2281
- 'openBids:',
2282
- openBids.toString()
2283
- );
2284
- assert(openBids.eq(new BN(9)));
2285
- assert(totalBidSize.eq(ZERO));
2286
-
2287
- const asks = Array.from(generator.getL2Asks());
2288
- // console.log(asks);
2289
-
2290
- const totalAskSize = asks.reduce((total: BN, order: L2Level) => {
2291
- return total.add(order.size);
2292
- }, ZERO);
2293
- console.log(
2294
- 'totalAskSize:',
2295
- totalAskSize.toString(),
2296
- 'openAsks:',
2297
- openAsks.toString()
2298
- );
2299
-
2300
- assert(openAsks.eq(new BN(-9)));
2301
- assert(totalAskSize.eq(ZERO));
2302
- });
2303
-
2304
- it('Reference Price Offset accounts for oracle twap slow floor term', () => {
2305
- // day-premium leg before averaging: 100000/1000*24 = 2400, then the
2306
- // program subtracts oracleTwapSlow.abs()/FUNDING_RATE_OFFSET_DENOMINATOR
2307
- // (500000/3333 = 150) => 2250. Without that term the average would be
2308
- // 1800 instead of 1750.
2309
- const reservePrice = PRICE_PRECISION;
2310
- const last24hAvgFundingRate = new BN(100000);
2311
- const liquidityFraction = new BN(2);
2312
- const oracleTwapFast = new BN(500000);
2313
- const markTwapFast = oracleTwapFast.add(new BN(1000));
2314
- const oracleTwapSlow = new BN(500000);
2315
- const markTwapSlow = oracleTwapSlow.add(new BN(2000));
2316
- const maxOffsetPct = 100000;
2317
-
2318
- const referencePriceOffset = calculateReferencePriceOffset(
2319
- reservePrice,
2320
- last24hAvgFundingRate,
2321
- liquidityFraction,
2322
- oracleTwapFast,
2323
- markTwapFast,
2324
- oracleTwapSlow,
2325
- markTwapSlow,
2326
- maxOffsetPct
2327
- );
2328
-
2329
- assert(referencePriceOffset.eq(new BN(1750)));
2330
- });
2331
-
2332
- it('calculateUpdatedAMM is a passthrough when the repeg debit fails the affordability floor', () => {
2333
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
2334
- const mockMarket1 = myMockPerpMarkets[0];
2335
- const mockAmm = mockMarket1.amm;
2336
-
2337
- mockAmm.baseAssetReserve = new BN(1000).mul(BASE_PRECISION);
2338
- mockAmm.quoteAssetReserve = new BN(1000).mul(BASE_PRECISION);
2339
- mockAmm.sqrtK = new BN(1000).mul(BASE_PRECISION);
2340
- mockAmm.pegMultiplier = new BN(10).mul(PEG_PRECISION);
2341
- mockAmm.baseAssetAmountWithAmm = new BN(100).mul(BASE_PRECISION);
2342
- mockAmm.curveUpdateIntensity = 100;
2343
- mockAmm.maxSpread = 25000;
2344
- // tiny positive equity: any positive repeg cost blows through it
2345
- mockAmm.totalFeeMinusDistributions = new BN(10);
2346
- mockAmm.netRevenueSinceLastFunding = new BN(0);
2347
-
2348
- const directionToClose = mockAmm.baseAssetAmountWithAmm.gt(ZERO)
2349
- ? PositionDirection.SHORT
2350
- : PositionDirection.LONG;
2351
- const [terminalQuoteAssetReserve] = calculateAmmReservesAfterSwap(
2352
- mockAmm,
2353
- 'base',
2354
- mockAmm.baseAssetAmountWithAmm.abs(),
2355
- getSwapDirection('base', directionToClose)
2356
- );
2357
- mockAmm.terminalQuoteAssetReserve = terminalQuoteAssetReserve;
2358
-
2359
- // a 1% oracle move is well inside half of maxSpread (1.25%), so the
2360
- // optimal-peg/budget calc doesn't take the large-price-gap escape
2361
- // hatch that would otherwise clear checkLowerBound
2362
- const mmOraclePriceData: MMOraclePriceData = {
2363
- price: new BN(101).mul(PRICE_PRECISION).divn(10),
2364
- slot: new BN(0),
2365
- confidence: new BN(1),
2366
- hasSufficientNumberOfDataPoints: true,
2367
- isMMOracleActive: true,
2368
- } as MMOraclePriceData;
2369
-
2370
- const updatedAmm = calculateUpdatedAMM(mockAmm, mmOraclePriceData);
2371
-
2372
- assert(updatedAmm.pegMultiplier.eq(mockAmm.pegMultiplier));
2373
- assert(updatedAmm.baseAssetReserve.eq(mockAmm.baseAssetReserve));
2374
- assert(updatedAmm.quoteAssetReserve.eq(mockAmm.quoteAssetReserve));
2375
- assert(updatedAmm.sqrtK.eq(mockAmm.sqrtK));
2376
- assert(
2377
- updatedAmm.totalFeeMinusDistributions.eq(
2378
- mockAmm.totalFeeMinusDistributions
2379
- )
2380
- );
2381
- });
2382
-
2383
- it('calculateUpdatedAMM is a passthrough when the oracle price is non-positive', () => {
2384
- const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
2385
- const mockMarket1 = myMockPerpMarkets[0];
2386
- const mockAmm = mockMarket1.amm;
2387
- mockAmm.curveUpdateIntensity = 100;
2388
-
2389
- const mmOraclePriceData: MMOraclePriceData = {
2390
- price: ZERO,
2391
- slot: new BN(0),
2392
- confidence: new BN(1),
2393
- hasSufficientNumberOfDataPoints: true,
2394
- isMMOracleActive: true,
2395
- } as MMOraclePriceData;
2396
-
2397
- const updatedAmm = calculateUpdatedAMM(mockAmm, mmOraclePriceData);
2398
- assert(updatedAmm.pegMultiplier.eq(mockAmm.pegMultiplier));
2399
- assert(updatedAmm.baseAssetReserve.eq(mockAmm.baseAssetReserve));
2400
- assert(updatedAmm.quoteAssetReserve.eq(mockAmm.quoteAssetReserve));
2401
- });
2402
- });