@@ -69,6 +69,13 @@ export const DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS = [
6969 new BN ( 5000 ) . mul ( QUOTE_PRECISION ) ,
7070] ;
7171
72+ export const MAJORS_TOP_OF_BOOK_QUOTE_AMOUNTS = [
73+ new BN ( 5000 ) . mul ( QUOTE_PRECISION ) ,
74+ new BN ( 10000 ) . mul ( QUOTE_PRECISION ) ,
75+ new BN ( 20000 ) . mul ( QUOTE_PRECISION ) ,
76+ new BN ( 50000 ) . mul ( QUOTE_PRECISION ) ,
77+ ] ;
78+
7279/**
7380 * Get an {@link Generator<L2Level>} generator from a {@link Generator<DLOBNode>}
7481 * @param dlobNodes e.g. {@link DLOB#getRestingLimitAsks} or {@link DLOB#getRestingLimitBids}
@@ -165,29 +172,21 @@ export function getVammL2Generator({
165172 marketAccount,
166173 oraclePriceData,
167174 numOrders,
168- now,
169- topOfBookQuoteAmounts,
175+ now = new BN ( Math . floor ( Date . now ( ) / 1000 ) ) ,
176+ topOfBookQuoteAmounts = [ ] ,
170177} : {
171178 marketAccount : PerpMarketAccount ;
172179 oraclePriceData : OraclePriceData ;
173180 numOrders : number ;
174181 now ?: BN ;
175182 topOfBookQuoteAmounts ?: BN [ ] ;
176183} ) : L2OrderBookGenerator {
177- let numBaseOrders = numOrders ;
178- if ( topOfBookQuoteAmounts ) {
179- numBaseOrders = numOrders - topOfBookQuoteAmounts . length ;
180- assert ( topOfBookQuoteAmounts . length < numOrders ) ;
181- }
182-
183184 const updatedAmm = calculateUpdatedAMM ( marketAccount . amm , oraclePriceData ) ;
184-
185- const vammFillsDisabled = isOperationPaused (
185+ const paused = isOperationPaused (
186186 marketAccount . pausedOperations ,
187187 PerpOperation . AMM_FILL
188188 ) ;
189-
190- let [ openBids , openAsks ] = vammFillsDisabled
189+ let [ openBids , openAsks ] = paused
191190 ? [ ZERO , ZERO ]
192191 : calculateMarketOpenBidAsk (
193192 updatedAmm . baseAssetReserve ,
@@ -196,230 +195,110 @@ export function getVammL2Generator({
196195 updatedAmm . orderStepSize
197196 ) ;
198197
199- const minOrderSize = marketAccount . amm . minOrderSize ;
200- if ( openBids . lt ( minOrderSize . muln ( 2 ) ) ) {
201- openBids = ZERO ;
202- }
203-
204- if ( openAsks . abs ( ) . lt ( minOrderSize . muln ( 2 ) ) ) {
198+ if ( openBids . lt ( marketAccount . amm . minOrderSize . muln ( 2 ) ) ) openBids = ZERO ;
199+ if ( openAsks . abs ( ) . lt ( marketAccount . amm . minOrderSize . muln ( 2 ) ) )
205200 openAsks = ZERO ;
206- }
207201
208- now = now ?? new BN ( Date . now ( ) / 1000 ) ;
209202 const [ bidReserves , askReserves ] = calculateSpreadReserves (
210203 updatedAmm ,
211204 oraclePriceData ,
212205 now ,
213206 isVariant ( marketAccount . contractType , 'prediction' )
214207 ) ;
215208
216- let numBids = 0 ;
217-
218- let topOfBookBidSize = ZERO ;
219- let bidSize = openBids . div ( new BN ( numBaseOrders ) ) ;
220- const bidAmm = {
221- baseAssetReserve : bidReserves . baseAssetReserve ,
222- quoteAssetReserve : bidReserves . quoteAssetReserve ,
223- sqrtK : updatedAmm . sqrtK ,
209+ const numBaseOrders = Math . max ( 1 , numOrders - topOfBookQuoteAmounts . length ) ;
210+ const commonOpts = {
211+ numOrders,
212+ numBaseOrders,
213+ oraclePriceData,
214+ orderTickSize : marketAccount . amm . orderTickSize ,
215+ orderStepSize : marketAccount . amm . orderStepSize ,
224216 pegMultiplier : updatedAmm . pegMultiplier ,
217+ sqrtK : updatedAmm . sqrtK ,
218+ topOfBookQuoteAmounts,
225219 } ;
226220
227- const getL2Bids = function * ( ) {
228- while ( numBids < numOrders && bidSize . gt ( ZERO ) ) {
229- let quoteSwapped = ZERO ;
230- let baseSwapped = ZERO ;
231- let [ afterSwapQuoteReserves , afterSwapBaseReserves ] = [ ZERO , ZERO ] ;
232-
233- if ( topOfBookQuoteAmounts && numBids < topOfBookQuoteAmounts ?. length ) {
234- const remainingBaseLiquidity = openBids . sub ( topOfBookBidSize ) ;
221+ const makeL2Gen = ( {
222+ openLiquidity,
223+ startReserves,
224+ swapDir,
225+ positionDir,
226+ } : {
227+ openLiquidity : BN ;
228+ startReserves : { baseAssetReserve : BN ; quoteAssetReserve : BN } ;
229+ swapDir : SwapDirection ;
230+ positionDir : PositionDirection ;
231+ } ) => {
232+ return function * ( ) {
233+ let count = 0 ;
234+ let topSize = ZERO ;
235+ let size = openLiquidity . abs ( ) . divn ( commonOpts . numBaseOrders ) ;
236+ const amm = {
237+ ...startReserves ,
238+ sqrtK : commonOpts . sqrtK ,
239+ pegMultiplier : commonOpts . pegMultiplier ,
240+ } ;
235241
236- baseSwapped = standardizeBaseAssetAmount (
237- topOfBookQuoteAmounts [ numBids ]
242+ while ( count < commonOpts . numOrders && size . gt ( ZERO ) ) {
243+ let baseSwap = size ;
244+ if ( count < commonOpts . topOfBookQuoteAmounts . length ) {
245+ const raw = commonOpts . topOfBookQuoteAmounts [ count ]
238246 . mul ( AMM_TO_QUOTE_PRECISION_RATIO )
239247 . mul ( PRICE_PRECISION )
240- . div ( oraclePriceData . price ) ,
241- marketAccount . amm . orderStepSize
242- ) ;
243-
244- if ( baseSwapped . eq ( ZERO ) ) {
245- return ;
248+ . div ( commonOpts . oraclePriceData . price ) ;
249+ baseSwap = standardizeBaseAssetAmount ( raw , commonOpts . orderStepSize ) ;
250+ const remaining = openLiquidity . abs ( ) . sub ( topSize ) ;
251+ if ( remaining . lt ( baseSwap ) ) baseSwap = remaining ;
246252 }
253+ if ( baseSwap . isZero ( ) ) return ;
247254
248- [ afterSwapQuoteReserves , afterSwapBaseReserves ] =
249- calculateAmmReservesAfterSwap (
250- bidAmm ,
251- 'base' ,
252- baseSwapped ,
253- SwapDirection . ADD
254- ) ;
255-
256- quoteSwapped = calculateQuoteAssetAmountSwapped (
257- bidAmm . quoteAssetReserve . sub ( afterSwapQuoteReserves ) . abs ( ) ,
258- bidAmm . pegMultiplier ,
259- SwapDirection . ADD
255+ const [ newQuoteRes , newBaseRes ] = calculateAmmReservesAfterSwap (
256+ amm ,
257+ 'base' ,
258+ baseSwap ,
259+ swapDir
260260 ) ;
261- if ( remainingBaseLiquidity . lt ( baseSwapped ) ) {
262- baseSwapped = remainingBaseLiquidity ;
263- [ afterSwapQuoteReserves , afterSwapBaseReserves ] =
264- calculateAmmReservesAfterSwap (
265- bidAmm ,
266- 'base' ,
267- baseSwapped ,
268- SwapDirection . ADD
269- ) ;
270-
271- quoteSwapped = calculateQuoteAssetAmountSwapped (
272- bidAmm . quoteAssetReserve . sub ( afterSwapQuoteReserves ) . abs ( ) ,
273- bidAmm . pegMultiplier ,
274- SwapDirection . ADD
275- ) ;
276- }
277- topOfBookBidSize = topOfBookBidSize . add ( baseSwapped ) ;
278- bidSize = openBids . sub ( topOfBookBidSize ) . div ( new BN ( numBaseOrders ) ) ;
279- } else {
280- baseSwapped = bidSize ;
281- [ afterSwapQuoteReserves , afterSwapBaseReserves ] =
282- calculateAmmReservesAfterSwap (
283- bidAmm ,
284- 'base' ,
285- baseSwapped ,
286- SwapDirection . ADD
287- ) ;
288-
289- quoteSwapped = calculateQuoteAssetAmountSwapped (
290- bidAmm . quoteAssetReserve . sub ( afterSwapQuoteReserves ) . abs ( ) ,
291- bidAmm . pegMultiplier ,
292- SwapDirection . ADD
293- ) ;
294- }
295-
296- const price = standardizePrice (
297- quoteSwapped . mul ( BASE_PRECISION ) . div ( baseSwapped ) ,
298- marketAccount . amm . orderTickSize ,
299- PositionDirection . LONG
300- ) ;
301-
302- bidAmm . baseAssetReserve = afterSwapBaseReserves ;
303- bidAmm . quoteAssetReserve = afterSwapQuoteReserves ;
304-
305- yield {
306- price,
307- size : baseSwapped ,
308- sources : { vamm : baseSwapped } ,
309- } ;
310-
311- numBids ++ ;
312- }
313- } ;
314-
315- let numAsks = 0 ;
316- let topOfBookAskSize = ZERO ;
317- let askSize = openAsks . abs ( ) . div ( new BN ( numBaseOrders ) ) ;
318- const askAmm = {
319- baseAssetReserve : askReserves . baseAssetReserve ,
320- quoteAssetReserve : askReserves . quoteAssetReserve ,
321- sqrtK : updatedAmm . sqrtK ,
322- pegMultiplier : updatedAmm . pegMultiplier ,
323- } ;
324-
325- const getL2Asks = function * ( ) {
326- while ( numAsks < numOrders && askSize . gt ( ZERO ) ) {
327- let quoteSwapped : BN = ZERO ;
328- let baseSwapped : BN = ZERO ;
329- let [ afterSwapQuoteReserves , afterSwapBaseReserves ] = [ ZERO , ZERO ] ;
330-
331- if ( topOfBookQuoteAmounts && numAsks < topOfBookQuoteAmounts ?. length ) {
332- const remainingBaseLiquidity = standardizeBaseAssetAmount (
333- openAsks . mul ( new BN ( - 1 ) ) . sub ( topOfBookAskSize ) ,
334- marketAccount . amm . orderStepSize
261+ const quoteSwapped = calculateQuoteAssetAmountSwapped (
262+ amm . quoteAssetReserve . sub ( newQuoteRes ) . abs ( ) ,
263+ amm . pegMultiplier ,
264+ swapDir
335265 ) ;
336-
337- baseSwapped = standardizeBaseAssetAmount (
338- topOfBookQuoteAmounts [ numAsks ]
339- . mul ( AMM_TO_QUOTE_PRECISION_RATIO )
340- . mul ( PRICE_PRECISION )
341- . div ( oraclePriceData . price ) ,
342- marketAccount . amm . orderStepSize
266+ const price = standardizePrice (
267+ quoteSwapped . mul ( BASE_PRECISION ) . div ( baseSwap ) ,
268+ commonOpts . orderTickSize ,
269+ positionDir
343270 ) ;
344271
345- if ( baseSwapped . eq ( ZERO ) ) {
346- return ;
347- }
348-
349- [ afterSwapQuoteReserves , afterSwapBaseReserves ] =
350- calculateAmmReservesAfterSwap (
351- askAmm ,
352- 'base' ,
353- baseSwapped ,
354- SwapDirection . REMOVE
355- ) ;
356- quoteSwapped = calculateQuoteAssetAmountSwapped (
357- askAmm . quoteAssetReserve . sub ( afterSwapQuoteReserves ) . abs ( ) ,
358- askAmm . pegMultiplier ,
359- SwapDirection . ADD
360- ) ;
272+ amm . baseAssetReserve = newBaseRes ;
273+ amm . quoteAssetReserve = newQuoteRes ;
361274
362- if ( remainingBaseLiquidity . lt ( baseSwapped ) ) {
363- baseSwapped = remainingBaseLiquidity ;
364- [ afterSwapQuoteReserves , afterSwapBaseReserves ] =
365- calculateAmmReservesAfterSwap (
366- askAmm ,
367- 'base' ,
368- baseSwapped ,
369- SwapDirection . REMOVE
370- ) ;
371-
372- quoteSwapped = calculateQuoteAssetAmountSwapped (
373- askAmm . quoteAssetReserve . sub ( afterSwapQuoteReserves ) . abs ( ) ,
374- askAmm . pegMultiplier ,
375- SwapDirection . REMOVE
376- ) ;
275+ if ( count < commonOpts . topOfBookQuoteAmounts . length ) {
276+ topSize = topSize . add ( baseSwap ) ;
277+ size = openLiquidity
278+ . abs ( )
279+ . sub ( topSize )
280+ . divn ( commonOpts . numBaseOrders ) ;
377281 }
378- topOfBookAskSize = topOfBookAskSize . add ( baseSwapped ) ;
379282
380- askSize = openAsks
381- . abs ( )
382- . sub ( topOfBookAskSize )
383- . div ( new BN ( numBaseOrders ) ) ;
384- } else {
385- baseSwapped = askSize ;
386- [ afterSwapQuoteReserves , afterSwapBaseReserves ] =
387- calculateAmmReservesAfterSwap (
388- askAmm ,
389- 'base' ,
390- baseSwapped ,
391- SwapDirection . REMOVE
392- ) ;
393-
394- quoteSwapped = calculateQuoteAssetAmountSwapped (
395- askAmm . quoteAssetReserve . sub ( afterSwapQuoteReserves ) . abs ( ) ,
396- askAmm . pegMultiplier ,
397- SwapDirection . REMOVE
398- ) ;
283+ yield { price, size : baseSwap , sources : { vamm : baseSwap } } ;
284+ count ++ ;
399285 }
400-
401- const price = standardizePrice (
402- quoteSwapped . mul ( BASE_PRECISION ) . div ( baseSwapped ) ,
403- marketAccount . amm . orderTickSize ,
404- PositionDirection . SHORT
405- ) ;
406-
407- askAmm . baseAssetReserve = afterSwapBaseReserves ;
408- askAmm . quoteAssetReserve = afterSwapQuoteReserves ;
409-
410- yield {
411- price,
412- size : baseSwapped ,
413- sources : { vamm : baseSwapped } ,
414- } ;
415-
416- numAsks ++ ;
417- }
286+ } ;
418287 } ;
419288
420289 return {
421- getL2Bids,
422- getL2Asks,
290+ getL2Bids : makeL2Gen ( {
291+ openLiquidity : openBids ,
292+ startReserves : bidReserves ,
293+ swapDir : SwapDirection . ADD ,
294+ positionDir : PositionDirection . LONG ,
295+ } ) ,
296+ getL2Asks : makeL2Gen ( {
297+ openLiquidity : openAsks ,
298+ startReserves : askReserves ,
299+ swapDir : SwapDirection . REMOVE ,
300+ positionDir : PositionDirection . SHORT ,
301+ } ) ,
423302 } ;
424303}
425304
0 commit comments